Unified · Split
| @@ -0,0 +1,931 @@ | |||
| 1 | 20121205 | ||
| 2 | appl/cmd/mk/mksubdirs [issue 290 change suggested by powerman] | ||
| 3 | 20120918 | ||
| 4 | remove unused/unusable debug/setdebug from appl/lib/auth9.b; use crypt not keyring | ||
| 5 | 20120820 | ||
| 6 | emu/port/devip.c reset headers flag in Conv | ||
| 7 | 20120725 | ||
| 8 | increase KSTACK for Linux/arm | ||
| 9 | 20120615 | ||
| 10 | add configuration emu/FreeBSD/emu-g [powerman] | ||
| 11 | 20120509 | ||
| 12 | utils/libmach: add missing user stack top initialisers, minor changes to sync with 9 | ||
| 13 | 20120507 | ||
| 14 | mkfiles/mkfile-MacOSX-386 change cc to gcc | ||
| 15 | emu/MacOSX/win.c null out drawcursor | ||
| 16 | 20120424 | ||
| 17 | utils/cc/Posix.c and utils/c2l/Posix.c: correct definition of mydup for POSIX dup/dup2 | ||
| 18 | libbio/bprint.c error handling if flush or print fails | ||
| 19 | 20120305 | ||
| 20 | add -I$ROOT/(Plan9|Inferno)/include to CFLAGS in mkfiles/^(mkfile-Plan9* mkfile-Inferno*) | ||
| 21 | change specific object type to $OBJTYPE in the same | ||
| 22 | libmath/fdlibm/fdlibm.h and libmath/dtoa.c, if USE_FPdbleword defined, use FPdbleword to crack doubles into integers | ||
| 23 | 20120304 | ||
| 24 | rabin(2) added (preliminary) | ||
| 25 | 20120213 | ||
| 26 | styxservers: add .error operation (preliminary) | ||
| 27 | 20120116 | ||
| 28 | lib9.h: internally rename qsort as infqsort to avoid C library clash | ||
| 29 | lib9/qsort.c: include lib9.h | ||
| 30 | lib9/mkfile: move qsort to IMPORTFILES from COMMONFILES | ||
| 31 | 20120103 | ||
| 32 | avoid re-defining isnan; use isNaN instead | ||
| 33 | 20111231 | ||
| 34 | Linux/*/include/emu.h adjustments for USE_PTHREADS for non-x86 processors | ||
| 35 | 20111221 | ||
| 36 | add `...` uninterpreted string literals to limbo/lex.c, appl/cmd/limbo/lex.b | ||
| 37 | 20111215 | ||
| 38 | liblogfs,libnandfs: use logfsos.h (added to include) to make library source independent of os | ||
| 39 | add fonts/vera | ||
| 40 | add fonts/courier | ||
| 41 | 20111214 | ||
| 42 | change Linux port to use pthreads instead of clone directly | ||
| 43 | emu/Linux: rename os.c to os-clone.c; rename osp.c to os.c | ||
| 44 | emu/Linux/mkfile: remove -lrt, add kproc-pthreads.$O | ||
| 45 | Linux/*/include: define USE_PTHREADS | ||
| 46 | Linux/386/include/emu.h: increase KSTACK to 32k for Linux gethost* functions | ||
| 47 | 20111003 | ||
| 48 | libinterp/heap.c:/^dtype discount size of map [issue 258] | ||
| 49 | 20110820 | ||
| 50 | emu/*/devfs.c, emu/port/devfs-posix.c - stubs for osdisksize, Linux implementation of osdisksize | ||
| 51 | emu/port/devfs-posix.c - also try SOCK_DGRAM for AF_UNIX [issue 269] | ||
| 52 | 20110819 | ||
| 53 | appl/cmd/mk/mk.b - use raise "fail:..." for exit status [issue 268] | ||
| 54 | 20110629 | ||
| 55 | change x86 getcallerpc to avoid use of %ebp [issue 266] | ||
| 56 | change type of getcallerpc to uintptr from ulong | ||
| 57 | 20110619 | ||
| 58 | emu/port/devfs-posix.c: put major/minor st_dev into path without mapping (with luck) | ||
| 59 | emu/port/kproc-pthreads.c: ensure pthread stack is at least PTHREAD_STACK_MIN (plus slop) | ||
| 60 | 20110526 | ||
| 61 | change osyield in Windows to use SwitchToThread instead of sleep(0) [e-mail list] | ||
| 62 | 20110525 | ||
| 63 | utils/[5678kqv]c/mkfile - include -I. before $CFLAGS to ensure right gc.h [issue 264] | ||
| 64 | 20110516 | ||
| 65 | merge changes from vac branch of mechiel-inferno-os (googlecode) | ||
| 66 | 20110426 | ||
| 67 | emu/Linux/asm-arm.S linux system call interface changed [issue 215, mechiel] | ||
| 68 | 20110419 | ||
| 69 | libinterp/tk.c:/^Tk_rect shouldn't return non-canonical rectangles | ||
| 70 | /appl/wm/mand.b handle reshape to empty rectangles | ||
| 71 | 20110408 | ||
| 72 | appl/lib/json.b - have writeval produce same (correct) form as .text for Real [issue 230] | ||
| 73 | 20110407 | ||
| 74 | fix embarrassingly broken Lists->delete; add Lists->find [issue 257] | ||
| 75 | add some extra explanation to sys-dup(2) about fildes | ||
| 76 | 20110404 | ||
| 77 | update Nt/386/bin | ||
| 78 | /limbo/com.c - count constants in qualifiers, not qualifiers [issue 212, mechiel] | ||
| 79 | /appl/cmd/limbo/com.b [also issue 212] | ||
| 80 | 20110403 | ||
| 81 | secstore(2) and secstore(1) updated to implement writing [issue 256, mechiel] | ||
| 82 | 20110402 | ||
| 83 | revision to devsrv.c change [issue 244] to avoid two calls to delwaiting | ||
| 84 | 20110330 | ||
| 85 | call strtol not atoi for hex numbers [issue 255, mechiel] | ||
| 86 | 20110329 | ||
| 87 | utils/mkdir/mkdir.c - add -p option [mechiel, issue 250] | ||
| 88 | emu/Linux/mkfile - try searching -lpthread after -lrt for sem_* [issue 247] | ||
| 89 | emu/port/devfs-posix.c - treat unix domain sockets as files (open/read/write/close) [npe, rsc, issue 254] | ||
| 90 | emu/port/devfs-posix.c - use volatile correctly; slight code tidy | ||
| 91 | emu/lib9/errstr-posix.c replace EINTR's error string by Eintr's text | ||
| 92 | 20110315 | ||
| 93 | libtk/textw.c - fix mysterious control characters for editing (D and K) [issue 253, fix from mechiel] | ||
| 94 | 20110225 | ||
| 95 | split emu.h from lib9.h for all platforms | ||
| 96 | kproc in emu is now a void type as in os | ||
| 97 | 20110224 | ||
| 98 | move private mem flag to Progs [issue 240, mechiel] | ||
| 99 | 20110224 | ||
| 100 | 20110208 | ||
| 101 | emu/Linux/os.c - use -lrt's semaphores instead of signals | ||
| 102 | emu/Linux/mkfile - add -lrt to library list, and push out separation of X11LIBS from SYSLIBS for emu-g done ages ago | ||
| 103 | 20110126 | ||
| 104 | emu/MacOSX/os.c - move a free to a more sensible place | ||
| 105 | 20110117 | ||
| 106 | emu/Nt/ipif.c changed to work with ipv6 interface changes | ||
| 107 | 20110116 | ||
| 108 | add Plan9/arm support [provided by richard miller] | ||
| 109 | 20110110 | ||
| 110 | utils/libmach/qdb.c [issue 245] restore renaming of qdiv as qmuldiv | ||
| 111 | 20110104 | ||
| 112 | emu/MacOSX/win.c detect double clicks [issue 232, jas] | ||
| 113 | emu/MacOSX/os.c replace erendezvous by a per-kproc semaphore for osblock/osready | ||
| 114 | 20101220 | ||
| 115 | changes to srv(3) to notify client when server vanishes [issue 244, thanks to powerman and roger] | ||
| 116 | 20101205 | ||
| 117 | change a few types in ipif-posix.c to appease the gods | ||
| 118 | emu/MacOSX/mkfile - include portmkfile at correct point for LIBFILES to work (and other, minor, changes) [issue 24] | ||
| 119 | 20101127 | ||
| 120 | emu/port/*ip*.[ch] and emu/Nt/ipif*.c updated with new interface for ipv6 support [mechiel] [issue 193] | ||
| 121 | emu/Linux/os.c address compilation warnings (setfcr etc still to do) | ||
| 122 | 20101125 | ||
| 123 | asm/assem.c don't attempt to use missing src (issue 243) | ||
| 124 | 20100925 | ||
| 125 | appl/lib/w3c/uris.b - handle existing Unicode characters if they happen not to have been encoded into string | ||
| 126 | appl/svc/httpd/parser.b - similar [response to issue 233] | ||
| 127 | 20100914 | ||
| 128 | emu/Nt/os.c - replace trap handling | ||
| 129 | 20100822 | ||
| 130 | correct handling of mouse focus in sub-widgets of widget windowed in text [issue 241] | ||
| 131 | add various warnings to mkfile-Linux-386 | ||
| 132 | 20100821 | ||
| 133 | correct handling of mouse focus in sub-widgets of widget windowed in canvas [issue 241] | ||
| 134 | 20100819 | ||
| 135 | failed to push Solaris/sparc/include/lib9.h with u64int change [issue 151] | ||
| 136 | appl/cmd/ar.b eliminate false error return | ||
| 137 | 20100810 | ||
| 138 | initial introduction of crypt-*(2) and ipints(2) | ||
| 139 | replace keyring.m in module/runt.m by ipints.m and crypt.m; compensate in libinterp and libkeyring by using keyringif.m to generate Keyring's interface | ||
| 140 | 20100802 | ||
| 141 | various changes held back by accident, notably stackv in stack(1), better diagnostics by cat(1) | ||
| 142 | 20100801 | ||
| 143 | libtk/coval.c - simplify vlong expression for some compilers [issue 216, mechiel] | ||
| 144 | 20100727 | ||
| 145 | on Linux and MacOSX, look at faulting address to decide if it's dereference of nil | ||
| 146 | 20100722 | ||
| 147 | include/bio.h add varargck and repair resulting diagnostics in utils and limbo/ [issue 237, mechiel] | ||
| 148 | 20100719 | ||
| 149 | appl/cmd/disk/mkfs.b change getname/getpath to cope with missing newline [issue 236] | ||
| 150 | 20100715 | ||
| 151 | appl/wm/toolbar.b changed not to create new /chan/snarf if one exists, unless -p (private) option given [toolbar(1)] | ||
| 152 | utils/cc/macbody - add overlooked change to implement __VA_ARGS__ | ||
| 153 | other minor updates to the compilers to resync | ||
| 154 | 20100714 | ||
| 155 | correctly initialise types in utils/cc/sub.c | ||
| 156 | 20100504 | ||
| 157 | change lib9/strtoull.c for MS | ||
| 158 | 20100503 | ||
| 159 | updated libmach/8db.c to avoid [] initialisers | ||
| 160 | 20100501 | ||
| 161 | update libmach to compensate for MS compiler | ||
| 162 | 20100426 | ||
| 163 | updated libmach | ||
| 164 | updated compiler suites (continuing) | ||
| 165 | 20100425 | ||
| 166 | appl/wm/wm.b shorten processing of wmctl close if client hadn't started | ||
| 167 | 20100406 | ||
| 168 | fix handling of boundary case in libtk/utils.c | ||
| 169 | 20100402 | ||
| 170 | add new option OPTflags to libtk for later use | ||
| 171 | 20100325 | ||
| 172 | more swizzling of libtk for later use. revised radio and check buttons. | ||
| 173 | 20100322 | ||
| 174 | a few tweaks to Tk for later use | ||
| 175 | 20100320 | ||
| 176 | appl/lib/json.b dis/lib/json.dis - use %f not string <real-value> to ensure json value acceptable [issue 230, powerman] | ||
| 177 | 20100310 | ||
| 178 | stop tabs(2) from issuing pointless tk cmd that produces diagnostics | ||
| 179 | 20100305 | ||
| 180 | add emu/Linux/audio-oss.c from saoret.one [issue 226] | ||
| 181 | 20100226 | ||
| 182 | mention -n nvram option in keyfs(4) | ||
| 183 | 20100220 | ||
| 184 | appl/cmd/keyfs.b wasn't clunking fids on error in remove [issue 225] | ||
| 185 | 20100213 | ||
| 186 | apply saoret.one's changes for thumb [issue 155] | ||
| 187 | 20100205 | ||
| 188 | update man pages to replace most references to Styx by 9P | ||
| 189 | update man pages to replace references to sys-dial(2) by dial(2) | ||
| 190 | add DragonFly files (from fgudin and extrudedaluminiu, issue 181); possibly should automatically keep aligned with FreeBSD | ||
| 191 | fpe handling in OpenBSD and FreeBSD [mechiel, issue 190] | ||
| 192 | appl/cmd/vacfs.b apply fix from mechiel [issue 204] | ||
| 193 | 20100203 | ||
| 194 | appl/lib/cfg.b treat \r as white space [issue 69, issue 70] | ||
| 195 | add u64int to lib9.h files that needed it | ||
| 196 | add sha2.c sha256block.c sha512block.c to libsec/port and include/libsec.h [issue 185, mechiel] | ||
| 197 | add new sha functions to module/keyring.m and libinterp/keyring.c | ||
| 198 | 20100115 | ||
| 199 | appl/cmd/tarfs.b man/4/tarfs changes to permission handling from mechiel [issue 220] | ||
| 200 | appl/spree/mkfile add explicit -I$ROOT/module [issue 209, powerman] | ||
| 201 | 20100110 | ||
| 202 | appl/cmd/tcs.b [issue 12, arvindht]: process unconverted bytes next cycle, flush conversion state; improve error checking | ||
| 203 | 20091219 | ||
| 204 | change default roots in Nt utils to c:\inferno | ||
| 205 | 20091215 | ||
| 206 | factotum(2) updated to include keyspec in signature | ||
| 207 | appl/cmd/mount.b uses -k value as keyspec if -9 selected [not to much purpose with current factotum's p9any] | ||
| 208 | bind(1) [for mount] updated to describe -k used for keyspec if -9 selected | ||
| 209 | 20091214 | ||
| 210 | switch more commands to use dial(2) | ||
| 211 | change emu/Linux/emu-g not to require X11 libs (again) | ||
| 212 | 20091213 | ||
| 213 | temper the tendancy of port/dis.c to yield during idle gc: it's compensating for os scheduling, but yield less often | ||
| 214 | 20091208 | ||
| 215 | add mkdir -p to makemk.sh to ensure output directories exist [issue 213] | ||
| 216 | 20091127 | ||
| 217 | problems fixed in styxconv(2), which can now convert both ways [rog] | ||
| 218 | 20091119 | ||
| 219 | emu/port/devfs-posix.c missing waserror in dirread (obscure but possible failure) | ||
| 220 | 20091007 | ||
| 221 | remove intermediate exception-raising function from charon implementation | ||
| 222 | 20091004 | ||
| 223 | restore "keyring" to lib section of emu/Plan9/emu | ||
| 224 | 20090930 | ||
| 225 | emu/*/ipif*.c make "hangup" act as in native Inferno; also delete unused so_setsockopt | ||
| 226 | provide correct version of devmnt.c | ||
| 227 | 20090928 | ||
| 228 | update import(4) to remove the restriction to Plan 9 (can use Inferno's own factotum) | ||
| 229 | (emu os)^/port/devmnt.c fix from plan 9 (don't access vanished data) | ||
| 230 | 20090830 | ||
| 231 | check subexp length in ed [cmbrannon79] | ||
| 232 | 20090825 | ||
| 233 | add netmkaddr call to /appl/cmd/ftpfs.b; send errors to standard error | ||
| 234 | 20090824 | ||
| 235 | delete unused (and somewhat incomplete) pin support | ||
| 236 | 20090822 | ||
| 237 | in the what were we thinking dept: appl/cmd/touch.b and dis/touch.dis updated to avoid using an Arg after nil'ing it [thanks to cmbrannon] | ||
| 238 | make progmode propagate to pgrps; recover from exceptions in pgrp creation | ||
| 239 | 20090821 | ||
| 240 | emu/Nt/^(os.c ie-os.c) add #include <excpt.h> | ||
| 241 | 20090819 | ||
| 242 | appl/cmd/mk/mk.b replace maketmp/mktemp (issue 202, mechiel); also old change: don't persist with bulkmtime on non-directories | ||
| 243 | 20090816 | ||
| 244 | registry(4) Event.post increased rootvers when entries are written or removed (issue 179, powerman) | ||
| 245 | 20090809 | ||
| 246 | bring mkfs(8) up to date (issue 176) | ||
| 247 | remove -q options from mkfs and mkext (-q was a transitional option to suppress quoting of file names) | ||
| 248 | 20090806 | ||
| 249 | increase `backlog' value in all listen calls in hosted Inferno (emu/*/ipif*.c) [powerman] | ||
| 250 | 20090805 | ||
| 251 | further checking added to libinterp/keyring.c: rejects incorrect states and out of bounds values of f->n | ||
| 252 | add lib/emptydirs and mkdirs target to /mkfile (utils/mkdir needs to be changed for Windows use) | ||
| 253 | 20090730 | ||
| 254 | improve the error checking in strtosk and strtopk to help detect mangled or inappropriate keys | ||
| 255 | 20090728 | ||
| 256 | emu/port/main.c: put host's working directory name as emuwdir | ||
| 257 | document initial environment variables in emu(1) | ||
| 258 | appl/lib/bufio.b dis/lib/bufio.dis [issue 199] don't lose track of actual file seek offset (following second suggestion of mjl) | ||
| 259 | issue 196: after general apologies for appl/svc/httpd/cache.b (don't look if you don't need it, not one of ours, etc. etc.) will patch as suggested by extrudedaluminiu(!) [vs] | ||
| 260 | 20090719 | ||
| 261 | correct order of operands to memset(!), eg in ipif [mjl] | ||
| 262 | 20090718 | ||
| 263 | fix appl/cmd/stream.b error exits to include fail: [mjl] | ||
| 264 | 20090717 | ||
| 265 | fix appl/lib/ip.b (see issue 186) [mjl] | ||
| 266 | re-enable XK_ keys in port/win-x11a.c [mjl] | ||
| 267 | 20090716 | ||
| 268 | add segflush calls to comp-386.c [probably need different name eventually to avoid time wasting when not needed] | ||
| 269 | 20090630 | ||
| 270 | add sig (see man(1)) [via p9p and caerwyn] | ||
| 271 | 20090627 | ||
| 272 | push changes described for arm in 20090330 (but not previously pushed) | ||
| 273 | begin change of inferno-os.googlecode.com from svn to mercurial | ||
| 274 | 200090612 | ||
| 275 | added support for Linux-power (ericvh; and further simplified) | ||
| 276 | 20090605 | ||
| 277 | appl/cmd/disk/kfs.b dis/disk/kfs.dis - don't try to update super block if readonly(!) [issue 175] | ||
| 278 | 20090526 | ||
| 279 | emu/Nt/os.c allow /dev/hoststdin input on file or pipe (thanks to caerwyn, issue 173) | ||
| 280 | emu/port/devfs-posix.c correct handling of error return from pread (issue 172, but goes beyond that) | ||
| 281 | emu/port/exportfs.c os/port/exportfs.c use vlong for offset | ||
| 282 | 20090524 | ||
| 283 | appl/cmd/tarfs.b dis/tarfs.dis - remove accidentally small limit on file size in tar file (issue 172) | ||
| 284 | 20090521 | ||
| 285 | module/vac.m appl/cmd/vacfs.b appl/lib/vac.b [issue 152] (Mecchiel) | ||
| 286 | 20090505 | ||
| 287 | add -h/-t header/trailer options to man2html | ||
| 288 | 20090430 | ||
| 289 | filter-deflate(2), appl/lib/^(inflate.b deflate.b): changes from mjl to support zlib headers for deflate streams as well as gzip's | ||
| 290 | 20090417 | ||
| 291 | add m4(1) in its initial form (might split the macro processing proper off into a library module) | ||
| 292 | 20090409 | ||
| 293 | tools/odbc/odbc.c data read should return 0 if no columns or rows (issue 170) | ||
| 294 | 20090408 | ||
| 295 | tools/odbc/odbc.c use strecpy and more care in allocation (issue 169) | ||
| 296 | 20090403 | ||
| 297 | change ,2 to ,#function in Solaris sparc assembler files (apparently works in gcc and sun's) | ||
| 298 | make appl/wm/brutus.b pass input to its widgets (issue 105) | ||
| 299 | enable fullscreen mode in MacOSX (issue 148) | ||
| 300 | 20090402 | ||
| 301 | add missing emu/Linux/segflush-*.c files and remove ARM segflush from os.c | ||
| 302 | 20090402 | ||
| 303 | ramfile and logfile shouldn't set Sys->MCREATE (issue 137) | ||
| 304 | 20090401 | ||
| 305 | appl/cmd/limbo/typecheck.b check correctly for function prevented from inline expansion | ||
| 306 | 20090330 | ||
| 307 | use (low, high) order for words in vlong and fp on arm: libinterp/comp-arm.c, Inferno/arm/include/^(lib9.h u.h) | ||
| 308 | also os/*/fpi.h (for arm platforms), exchanging order of ulongs in Double | ||
| 309 | also libkern/^(vlrt-arm.c vlop-arm.s vlop-thumb.s frexp-arm.c frexp-thumb.c) | ||
| 310 | include changes from richard miller for little-endian mips (spim) and Linux/spim hosted | ||
| 311 | libmath/dtoa.c: use simpler code to avoid gcc bug on mips and perhaps other platforms (rmiller) | ||
| 312 | 20090330-branches/forse | ||
| 313 | include appl/cmd/ssh source (won't compile here because it needs the keyring changes) | ||
| 314 | 20090325-branches/forse | ||
| 315 | emu/* adopt changes to Chan (Dev* dev pointer instead of int type) | ||
| 316 | 20090320 | ||
| 317 | emu/port/win-x11a.c: unintuitively use xdisplay not xkbdcon to send to kbdproc (with big stack) to change cursor | ||
| 318 | (the big stack is needed because XCreateBitmapFromData and XPutImage pass control to theme-related code that uses lots of stack space) | ||
| 319 | use uname not aname for user name in libstyx and set aname to "" by default | ||
| 320 | make odbc's new file have mode 666 so others can open it | ||
| 321 | add styxsetowner function to styxserver.h to set default owner (eve) | ||
| 322 | move styxserver.h to inferno's include directory | ||
| 323 | 20090222 | ||
| 324 | appl/cmd/ndb/registry.b and dis/registry.dis - implement flush for event file (issue 162) | ||
| 325 | 20090217 | ||
| 326 | appl/cmd/limbo/stubs.b limbo/stubs.c - include length parameter to builtinmod (could just be 0 in most cases) | ||
| 327 | change f->ret/destroy code in stubs.c/stubs.b to destroy correctly in case of exceptions | ||
| 328 | 20090202 | ||
| 329 | emu/port/win-x11a.c: might as well try this everywhere now | ||
| 330 | 20090127 | ||
| 331 | libinterp/xec.c: fix gc problem with self | ||
| 332 | 20090122 | ||
| 333 | libinterp/string.c: slicer can return H for empty slice after bounds check (brucee) | ||
| 334 | 20081119 | ||
| 335 | os/pc/^(main.c fns.h) more idle idlehands | ||
| 336 | 20081112 | ||
| 337 | emu/Linux/asm-arm.S old failure to use different regs for swp finally changed here | ||
| 338 | libmath/blas.c compensate for gcc bug on arm | ||
| 339 | 20081107 | ||
| 340 | replace calls to calloc by malloc | ||
| 341 | 20081106 | ||
| 342 | os/port/dis.c prevent new spawns during killgrp | ||
| 343 | also synchronise two killgrps of the same group | ||
| 344 | 20081105 | ||
| 345 | emu/port/dis.c prevent new spawns during killgrp [#117] | ||
| 346 | 20081022 | ||
| 347 | sh: ignore leading white space in fail: strings, and change empty tail to "failed" | ||
| 348 | /emu/port/devfs-posix.c don't call readdir after it has returned end of file | ||
| 349 | 20081021 | ||
| 350 | /appl/cmd/auth/ai2key.b new command to convert authinfo files to factotum keys | ||
| 351 | /appl/cmd/auth/factotum/proto/infauth.b allow new key format | ||
| 352 | 20081019 | ||
| 353 | /appl/cmd/man2html.b implement "\ " => " " | ||
| 354 | /man/3/prog change way a literal " was formatted | ||
| 355 | /man/8/srv deleted (obsolete) | ||
| 356 | removed reference to srv(8) from sys-pctl(2) | ||
| 357 | 20080909 | ||
| 358 | /appl/cmd/puttar.b add extra empty block at end of archive as required by format | ||
| 359 | 20080907 | ||
| 360 | include some changes from acme-sac in emu/Nt/devfs.c; need further control of usesec (or discard it) | ||
| 361 | 20080723 | ||
| 362 | rename Inferno's yacc to iyacc to avoid clash with system's own (now that Linux and others distribute it) | ||
| 363 | 20080707 | ||
| 364 | update emu/port/win-x11a.c (fix someone's earlier patch to stop using undefined value) | ||
| 365 | emu/port/main.c mark obsolete options and remove from usage | ||
| 366 | 20080705 | ||
| 367 | update utils/sed, eliminating anonymous unions (just by commenting them out, to keep source in step with 9) | ||
| 368 | and several other changes for portability | ||
| 369 | 20080703 | ||
| 370 | remove anonymous unions (and unused structs) from unpacking structures in emu/Nt/vlrt.c, not that it's used | ||
| 371 | 20080617 | ||
| 372 | win-x11a.c add sqweek's change to pass on KeyRelease values (but perhaps 1-byte values are no longer enough?) | ||
| 373 | 20080614 | ||
| 374 | change os/port/devcons.c to use error not panic in sysfatal | ||
| 375 | 20080612 | ||
| 376 | change several libmp/port functions to use sysfatal not abort | ||
| 377 | change emu/port/main.c to have sysfatal call error not exit | ||
| 378 | 20080611 | ||
| 379 | Keyring->dhparams to use DSAprimes in special case | ||
| 380 | IPint.random now ignores minint (will go next revision) | ||
| 381 | BigInt -> mpint* | ||
| 382 | checkIPint in libinterp/ipint.c | ||
| 383 | default keys in auth/createsignerkey are 1024 not 512 bits | ||
| 384 | update os/boot/pc | ||
| 385 | 20080610 | ||
| 386 | push sh-mload(1) and changes to sh-expr(1) | ||
| 387 | 20080609 | ||
| 388 | _tas type changed from ulong to int | ||
| 389 | 20080530 | ||
| 390 | issue 91: _declspec changed to __declspec in Nt files | ||
| 391 | issue 92: argv0 declaration changed to extern from static in emu/Nt/win.c | ||
| 392 | 20080529 | ||
| 393 | limbo/stubs.c: allow pick adt types | ||
| 394 | 20080528 | ||
| 395 | emu/port/win-x11a.c screen depth checks from drawterm via tim@nop.cx | ||
| 396 | 20080524 | ||
| 397 | add missing NetBSD files | ||
| 398 | 20080522 | ||
| 399 | dis/lib/msgio.dis appl/lib/msgio.b - fix incorrect check for 16rFF | ||
| 400 | add OpenBSD changes from tim@nop.cx (more changes to follow shortly that cause changes elsewhere) | ||
| 401 | 20080416 | ||
| 402 | fix emu/Nt/os.c use of wrong name for null value | ||
| 403 | move win/win-x11a references to emu/*/emu config files from emu/*/mkfile | ||
| 404 | 20080415 | ||
| 405 | googlecode update with correct dis files for acme | ||
| 406 | tidier code for hoststderr | ||
| 407 | emu/port/win-x11a.c changes that attempt to satisfy libxcb's locking requirements | ||
| 408 | 20080322 | ||
| 409 | enable hoststderr, following acme-sac | ||
| 410 | 20080319 | ||
| 411 | ip/sntp neither read nor set the time correctly | ||
| 412 | 20080311 | ||
| 413 | in appl/lib/names.b define "" as valid prefix for anything | ||
| 414 | 20080304 | ||
| 415 | auth/secstore uses dial module | ||
| 416 | 20080210 | ||
| 417 | add auth/dsagen | ||
| 418 | 20080204 | ||
| 419 | emu/*/*ipif*.c and devip.c: try to allow local address to be set (changes so_bind signature in emu/ip.h) | ||
| 420 | 20080201 | ||
| 421 | change foldbranch in limbo/gen.c to prevent loss of `no return value' diagnostics | ||
| 422 | 20080131 | ||
| 423 | update emu/Nt/^(os.c ie-os.c ie-win.c ie emu), but properly this time [issue 81] | ||
| 424 | remove _USE_32BIT_TIME_T from Nt/386/include/lib9.h, and time() def'n from emu/Nt/*.c [issue 81] | ||
| 425 | 20080130 | ||
| 426 | failed to return nil from Jvalue.get in appl/lib/json.b if member name didn't match | ||
| 427 | similar problem in appl/lib/ubfa.b | ||
| 428 | add msgio(2) | ||
| 429 | 20080124 | ||
| 430 | fix emu/port/devssl.c os/port/devssl.c not to keep the directory numbers(!) | ||
| 431 | 20080122 | ||
| 432 | update appl/lib/db.b: allow for split i/o on pipes or tcp/ip; eliminate lock process | ||
| 433 | eliminate more unused identifier warnings (courtesy acme-sac) | ||
| 434 | 20080121 | ||
| 435 | skip trailing '=' in b64 rep of IPint | ||
| 436 | 20080120 | ||
| 437 | forgot to push updated appl/lib/x509.b during keyring changes | ||
| 438 | 20080116 | ||
| 439 | add rsa to factotum | ||
| 440 | set but not used changes from Acme-sac | ||
| 441 | mdb(1) changes from Acme-sac | ||
| 442 | ftpfs uses new dial(2) | ||
| 443 | add qbypass to emu/port/qio.c | ||
| 444 | sed fix issue 49 | ||
| 445 | add blowfish to keyring-crypt(2) | ||
| 446 | add challenge/response to factotum(2) | ||
| 447 | 20080115 | ||
| 448 | add blowfish to keyring (not yet documented) | ||
| 449 | add explicit public and private key types to keyring (in development: not yet documented) | ||
| 450 | add IPint.mod, IPint.iptob64z | ||
| 451 | 20080111 | ||
| 452 | add newuser to newns(2) | ||
| 453 | 20080109 | ||
| 454 | Sys->iounit should accept any valid file descriptor, not just ORDWR | ||
| 455 | 20071227 | ||
| 456 | add styxflush(2) etc. | ||
| 457 | add NetBSD, emu/NetBSD | ||
| 458 | 20071217 | ||
| 459 | emu/port/devmnt.c needs volatile for alloc | ||
| 460 | 20071213 | ||
| 461 | emu/port/dev.c needs volatile for alloc | ||
| 462 | 20071129 | ||
| 463 | emu/port/devip.c: moan about bad IP addresses | ||
| 464 | 20071127 | ||
| 465 | added /module/dial.m and /appl/lib/dial.b | ||
| 466 | 20071031 | ||
| 467 | module/keyring.m and libinterp/keyring.c: add algorithm-specific adts for public key systems | ||
| 468 | appl/lib/spki/spki.b: correct names for dsa parameters | ||
| 469 | 20071030 | ||
| 470 | libkeyring/rsaalg.c should call rsaprivfree not free | ||
| 471 | 20071027 | ||
| 472 | appl/lib/names.b correction for "/" as prefix | ||
| 473 | 20071019 | ||
| 474 | change emu/port/devfs-posix.c to update uid/gid map incrementally | ||
| 475 | 20071015 | ||
| 476 | add cap creation to infauth in server role in factotum | ||
| 477 | 20071011 | ||
| 478 | remove obsolete references to sh-exception(2) | ||
| 479 | 20071010 | ||
| 480 | add abhey's changes for cmd key as unicode compose key for MacOS X to emu/MacOSX/win.c | ||
| 481 | 20071008 | ||
| 482 | nemo's change to emu/port/random.c; really the file needs a little rewriting for clarity (too many overlapping states) | ||
| 483 | 20071002 | ||
| 484 | ensure fmtdef.h included by some lib9 functions so that va_copy is defined on older systems that lack that needless notion | ||
| 485 | <{} and >{} added to sh(1) | ||
| 486 | 20070929 | ||
| 487 | move emu/MacOSX/mkfile to .../mkfile-x11 and replace it by the variant that builds for Carbon, now the default | ||
| 488 | 20070927 | ||
| 489 | add working drawcursor to emu/MacOSX/win.c, based on mirtchovski's changes (but mapping general cursor images to Mac's form) | ||
| 490 | 20070910 | ||
| 491 | update spki(2) [change handling of hashes, add signature functions] appl/lib/spki/spki.b module/spki.m, updated for GSoC | ||
| 492 | 20070906 | ||
| 493 | add toreal to string(2) | ||
| 494 | 20070905 | ||
| 495 | /appl/cmd/ed.b (caerwyn's fix for g/.../d) | ||
| 496 | also /appl/lib/ecmascript/builtin.b (toupper fix) | ||
| 497 | 20070902 | ||
| 498 | make /appl/lib/daytime.b accept Daytime->text's output; add string2tm to man page (issue 59) | ||
| 499 | 20070901 | ||
| 500 | add andrey's changes to emu/MacOSX/win.c (used by emu/MacOSX/mkfile-a) | ||
| 501 | add saoret's changes to dis/lookman, dis/man (issue 58) | ||
| 502 | add micah.stetson's change to /appl/cmd/src.b (issue 57) | ||
| 503 | 20070817 | ||
| 504 | two old changes that weren't in the distribution... | ||
| 505 | libkeyring/rsaalg.c: previously failed to ensure the output key was the right length (really rsagen should do that) | ||
| 506 | libinterp/alt.c: use a better random number generator | ||
| 507 | 20070814 | ||
| 508 | bufio.b didn't update the buffer pointers correctly on write errors | ||
| 509 | 20070807 | ||
| 510 | libinterp/keyring.c don't include owner= if owner is nil or "" | ||
| 511 | add auth/rsagen | ||
| 512 | 20070806 | ||
| 513 | /module/lists.m add PATH(!), also simplify concat implementation | ||
| 514 | 20070725 | ||
| 515 | /dis/man initialise fils correctly to empty list and remove hack (issue 56) | ||
| 516 | 20070720 | ||
| 517 | utils/5l/asm.c: ensure SBZ field in MOV is regarded as MBZ (ie, force to zero) | ||
| 518 | 20070714 | ||
| 519 | add Sys->readn, update sys-read(2) | ||
| 520 | copy two repairs from emu/port/inferno.c to os/port/inferno.c | ||
| 521 | remove readn implementation from several commands | ||
| 522 | print correct diagnostic in appl/cmd/crypt.b | ||
| 523 | prevent window titlebars from being dragged out of the main window in wm/wm.b | ||
| 524 | 20070619 | ||
| 525 | remembered to include /appl/cmd/trfs.b /dis/trfs.dis | ||
| 526 | 20070614 | ||
| 527 | /appl/lib/venti.b bug fixes, a few more errstrs, remove prints to stderr | ||
| 528 | add initial module/vac.m appl/lib/vac.b from mjl (gsoc project ventivac) | ||
| 529 | add initial /appl/cmd/^(vacfs.b vacget.b vacput.b) /man/4/vacfs /man/1/vacget from mjl (gsoc:ventivac) | ||
| 530 | include omitted man/mkfile man/lib | ||
| 531 | 20070608 | ||
| 532 | update /lib9 functions to use silly va_copy (and then va_end) instead of just assigning, to account for silly C implementations | ||
| 533 | change /appl/cmd/mc.b not to require Draw or Env (so lc works on smaller systems) | ||
| 534 | update acme to include the font size data (eg, for use by mc(1)) | ||
| 535 | 20070607 | ||
| 536 | /appl/wm/man.b /appl/lib/man.b to allow 10.1 etc as section references | ||
| 537 | 20070605 | ||
| 538 | add another xopen #define to lib9.h includes for Linux | ||
| 539 | copy plan9 acme's colormix | ||
| 540 | 20070601 | ||
| 541 | /appl/cmd/ls.b /dis/ls.dis /man/1/ls: document new -F option and -T option | ||
| 542 | /appl/cmd/auth/factotum/factotum.b: ignore empty writes, don't fail; make a few diagnostics match plan 9 | ||
| 543 | rename /appl/cmd/mc.b to /appl/cmd/calc.b; also /man/1/mc to /man/1/calc; /dis/mc.dis to /dis/calc.dis | ||
| 544 | add /appl/cmd/mc.b (initial version) | ||
| 545 | replace /dis/lc.dis by /dis/lc; remove /appl/cmd/lc.b | ||
| 546 | remove /appl/cmd/mathcalc.b /dis/mathcalc.dis /man/1/mathcalc | ||
| 547 | 20070510 | ||
| 548 | quickly remove references to udp's "oldheaders" because plan 9 removed it | ||
| 549 | remove obootpd completely | ||
| 550 | 20070418 | ||
| 551 | add scan code to X11 (issue 45) | ||
| 552 | 20070411 | ||
| 553 | if mkconfig has been changed from the distribution, use it to set parameters in makemk.sh (issue 41) | ||
| 554 | add iso8859-15 (what? will the line stretch on to the crack of doom?) (issue 43) | ||
| 555 | 20070410 | ||
| 556 | fix some porting errors in /appl/cmd/look.b | ||
| 557 | document look's -r option in look(1) | ||
| 558 | 20070407 | ||
| 559 | /os/port/^(portdat.h lib.h portfns.h xalloc.c) compatiblity changes with plan 9 | ||
| 560 | /os/pc ether drivers updated to match plan 9, and os/ip (and a few files in /os/port) also updated, including removing some unreachable code | ||
| 561 | /os/ip/tcp.c changes from plan 9 for out-of-sequence segments | ||
| 562 | 20070319 | ||
| 563 | emu/port/devsrv.c and os/port/devsrv.c delete wc at correct time | ||
| 564 | 20070312 | ||
| 565 | rename -D and -k options to plumb (old ones still accepted); add -i option to take data from standard input; update man page | ||
| 566 | enable 64-bit seeks in /emu/Nt/devfs.c | ||
| 567 | 20070302 | ||
| 568 | change /mkfile to build yacc earlier, mainly to make bootstrap of a new host easier (makemk.sh and mk install) | ||
| 569 | change /utils/mkfile not to build k[acl] and q[acl] on Plan 9, since the system ones are the same | ||
| 570 | 20070228 | ||
| 571 | make array bounds checking the default for on-the-fly compilers (emu/port/main.c) | ||
| 572 | improve wording in security-ssl(2) and ssl(3) | ||
| 573 | 20070227 | ||
| 574 | /include/fcall.h: ensure unsigned promotion to counter ansi sign-extending rules for GBIT64 | ||
| 575 | /libmemdraw/draw.c: copy fix to memfillcolor | ||
| 576 | 20070220 | ||
| 577 | add 0x92 as chip ID for ether91c111.c | ||
| 578 | 20070217 | ||
| 579 | repair /appl/lib/libc.b and /appl/lib/libc0.b strncmp implementations (used only by c2l output) [inferno-os issue 9] | ||
| 580 | /emu/port/devip.c, get socket fd on reopen of ctl | ||
| 581 | /appl/acme/exec.b, trim string correctly [inferno-os issue 11] | ||
| 582 | 20070216 | ||
| 583 | add /module/lists.m, /appl/lib/lists.b, and lists(2) | ||
| 584 | 20070209 | ||
| 585 | remove debugging -d option to exportfs call in emu/Plan9/devsrv9.c(!) | ||
| 586 | 20070206 | ||
| 587 | /appl/svc/auth.sh: replace exit by raise | ||
| 588 | /man/2/styxservers: document replychan and replydirect | ||
| 589 | 20070201 | ||
| 590 | update US timezone files to save energy | ||
| 591 | 20070131 | ||
| 592 | add /appl/lib/convcs/utf16_btos.b, utf16_stob.b etc [rog] | ||
| 593 | 20070130 | ||
| 594 | fix wording in some of the licence files (eg, remove references to old liberal licence) | ||
| 595 | 20070123 | ||
| 596 | check lengths properly in devenv.c | ||
| 597 | move all of doc into lib/proto/inferno from lib/proto/src | ||
| 598 | 20070122 | ||
| 599 | add doc/port.ms, doc/port.pdf to src proto. add brief instructions for source rebuild to port.ms | ||
| 600 | 20070118 | ||
| 601 | add json(2) {/appl/lib/json.b, /module/json.m, /dis/lib/json.dis} for RFC4627 notation [json(6)] | ||
| 602 | 20070117 | ||
| 603 | remove duplicate libmp/libsec reference from /mkfile (i assume it wasn't necessary to visit them twice!) | ||
| 604 | 20070116 | ||
| 605 | move Man from /dis/man.dis (which vanished a few changes ago) to /dis/lib/man.dis. honestly. wm/man works again. | ||
| 606 | 20070114 | ||
| 607 | remove some unused static declarations in /utils/mk/shprint.c | ||
| 608 | 20070111 | ||
| 609 | delete drawxflush from devdraw.c (call drawq(un)?lock instead) | ||
| 610 | 20070107 | ||
| 611 | have emu (/emu/port/main.c) check environment variables INFERNO and ROOT before EMU and -r, for inferno root directory | ||
| 612 | (haven't yet changed the build system and mkfiles to match) | ||
| 613 | remove /include/libcrypt_o.h since the library isn't used | ||
| 614 | add complete(2) | ||
| 615 | 20070103 | ||
| 616 | replace man.dis by Salva Peiró's sh version of plan 9's man script | ||
| 617 | 20061221 | ||
| 618 | add data2c to Irix package prototype | ||
| 619 | remove unwanted .dis/.sbl files from /appl packages | ||
| 620 | change liblogfs to GPLv2 from proprietary, to fit google code | ||
| 621 | correct cmd(3) to account for new stderr file | ||
| 622 | 20061219 | ||
| 623 | cmd(3) and thus os(1) change to separate standard output and error streams | ||
| 624 | all /emu/*/cmd.c change to account for that (original changes to devcmd.c and MacOSX/cmd.c courtesy Cibernet) | ||
| 625 | 20061215 | ||
| 626 | replaced things like <???> because gcc annoyingly whines even with 1950's trigraphs off | ||
| 627 | libtk/textu.c: uninitialised field in boundary case | ||
| 628 | libtk/textw.c: possibly uninitialised value; leave unchanged | ||
| 629 | utils/ql/l.h: uchar as to ushort, because of extra ops | ||
| 630 | 20061214 | ||
| 631 | added fopen to xml.m to allow bufio->sopen and others to be used | ||
| 632 | 20061213 | ||
| 633 | added MacOSX/386 components | ||
| 634 | 20061013 | ||
| 635 | updated /os/ip/lookbackmedium.c and /os/ip/rudp.c | ||
| 636 | 20061021 | ||
| 637 | change /os/port/exportfs.c to allow negotiating up to 64k msize | ||
| 638 | (matching /emu/port/exportfs.c) | ||
| 639 | 20060809 | ||
| 640 | /appl/lib/newns.b uses String->unquoted, if it can load it | ||
| 641 | 20060803 | ||
| 642 | /libtk/textw.c: default page up/down scrolls 0.75 of a page (to give context); also allows fractional value | ||
| 643 | 20060801 | ||
| 644 | /utils/data2s/data2s.c: allocate at least one linker byte to empty files to avoid complaints | ||
| 645 | 20060715 | ||
| 646 | /appl/lib/pop3.b remove defaultserver(); update pop3(2) to remove references to /services | ||
| 647 | similarly update smtp(2) | ||
| 648 | avoid some boundary cases in /appl/charon/^(build.b layout.b) | ||
| 649 | 20060625 | ||
| 650 | added caerwynj@gmail.com changes to /appl/acme/acme/mail/src/Mailpop3.b | ||
| 651 | 20060622 | ||
| 652 | /appl/lib/sets*.b: correct op's implementation of 2r1101 | ||
| 653 | 20060613 | ||
| 654 | added csv(2), /module/csv.m, /appl/lib/csv.b | ||
| 655 | 20060608 | ||
| 656 | preliminary rfc822(2), /appl/lib/rfc822.b | ||
| 657 | 20060605 | ||
| 658 | /appl/lib/chanfill.b: remove alt => * | ||
| 659 | 20060601 | ||
| 660 | fix /appl/lib/dis.b to save the real array once read in | ||
| 661 | 20060526 | ||
| 662 | /appl/lib/venti.b: fix g64's byte ordering [not that it is, or can be called yet] | ||
| 663 | 20060524 | ||
| 664 | copy end fix to lib*/utfecpy.c | ||
| 665 | 20060523 | ||
| 666 | w3c-uris(2): add a .copy() operation | ||
| 667 | 20060518 | ||
| 668 | /Nt/386/include/lib9.h define _USE_32BIT_TIME_T and deprecate `deprecated' warnings | ||
| 669 | 20060504 | ||
| 670 | remove use of HEAP_ALIGN from /*/port/devprof.c; change Heap.pad to Heap.hprof in /include/interp.h | ||
| 671 | 20060426 | ||
| 672 | correct text and selection colours in wm/sh for loss-of-focus and holding modes | ||
| 673 | 20060423 | ||
| 674 | add /appl/lib/w3c/uris.b w3c-uris(2) /module/uris.m | ||
| 675 | 20060419 | ||
| 676 | /emu/port/devcmd.c: correct wakeup state for started command | ||
| 677 | 20060412 | ||
| 678 | /appl/svc/webget include caerwyn's changes | ||
| 679 | 20060411 | ||
| 680 | put `|| exit 1' after each (command-list) in the mkfiles, just for bash | ||
| 681 | 20060410 | ||
| 682 | /appl/cmd/limbo/typecheck.b /limbo/typecheck.c - stop wrong warning wrt use of ref fn | ||
| 683 | 20060313 | ||
| 684 | remembered to install cddb port from last year... cddb(7) | ||
| 685 | 20060312 | ||
| 686 | /emu/Nt/win.c; #define windows names out of the way to remove IPoint etc | ||
| 687 | /emu/Nt/os.c, simplify osblock/osready and eliminate erendezvous | ||
| 688 | /emu/port/devcons.c, tug into line with /os/port, to prepare for single-window changes | ||
| 689 | echo ^U on CAN (ctrl-U) | ||
| 690 | 20060311 | ||
| 691 | replace Limbo version of shutdown by sh script; it's still a bit silly | ||
| 692 | 20060309 | ||
| 693 | /*/port/inferno.c: 0 or -1 return value from dial functions | ||
| 694 | /os/port/portmkfile: remove reference to ../kfs | ||
| 695 | /man/8/httpd document -a; /appl/svc/httpd/httpd.b | ||
| 696 | /libmp/port/mptouv.c sign extension fix from 9 | ||
| 697 | /module/keyring.m, /libinterp/ipint.c: add some bitwise operators | ||
| 698 | change (undocumented) /appl/cmd/test.b so that `host' mkfiles will work in Inferno | ||
| 699 | should probably change the mkfiles to replace it | ||
| 700 | 20060303 | ||
| 701 | /emu/Plan9/win.c replace ldepthof | ||
| 702 | 20060302 | ||
| 703 | add KPX11 flag to hosted kproc to boost the stack for silly x11 & co. | ||
| 704 | put keyboard and cursor processing into a separate kproc with big stack in /emu/port/win-x11a.c | ||
| 705 | change various os.c to match | ||
| 706 | 20060301 | ||
| 707 | /appl/cmd/rioimport.b fix initialisation race | ||
| 708 | 20060227 | ||
| 709 | fix /utils/ql/l.h: oprange should be [ALAST] (with extra 405xx opcodes), also AEND->ALIST elsewhere | ||
| 710 | put faster gethunk in ql and kl (mimic other compilers) | ||
| 711 | 20060226 | ||
| 712 | enable /emu/port/devpointer.c, with changes to /emu/*/win*.c to call mousetrack, /emu/port/main.c to bind #m, | ||
| 713 | and code for pointer and cursor removed from devcons.c | ||
| 714 | update Nt/win.c and port/win-x11a.c from drawterm to get/put host snarf buffer | ||
| 715 | change devmem.c from #m to #% not to clash with pointer | ||
| 716 | 20060225 | ||
| 717 | add /emu/port/devsnarf.c (#^) and put clipread from drawterm in /emu/Nt/win.c | ||
| 718 | 20060224 | ||
| 719 | modify /appl/lib/secstore.b, /module/secstore.m, secstore(2) [add dial, auth, mkseckey, mkfilekey, remove] | ||
| 720 | add /appl/cmd/auth/secstore.b, secstore(1) | ||
| 721 | remove strange exception handling in /appl/cmd/dd.b | ||
| 722 | add dhcpclient(2) | ||
| 723 | 20060223 | ||
| 724 | add /appl/cmd/auth/aescbc.c | ||
| 725 | add /appl/cmd/crypt.b [rog] | ||
| 726 | add crypt(1) | ||
| 727 | add /appl/lib/secstore.b /module/secstore.m secstore(2) | ||
| 728 | 20060221 | ||
| 729 | /libsec/port/hmac.c: treat existing but not seeded digest correctly | ||
| 730 | /libinterp/ipint.c, /module/keyring.m, add new operator `invert' | ||
| 731 | 20060220 | ||
| 732 | add ida(2), /appl/lib/ida, /module/ida.m | ||
| 733 | 20060216 | ||
| 734 | add ubfa(2), ubfa(6), /module/ubfa.m, /appl/lib/ubfa.b | ||
| 735 | 20060214 | ||
| 736 | [rog] add cursor changing support to tk, wm, wmlib (eg, for acme) | ||
| 737 | 20060213 | ||
| 738 | remove libcrypt_o from distribution | ||
| 739 | 20060211 | ||
| 740 | add /man/1/9win [rog] | ||
| 741 | change /appl/cmd/auth/keyfs.b to confirm key only when creating the file [rog] | ||
| 742 | punt floating-point conversions in powerpc jit on macos for time being | ||
| 743 | (have particular values in certain FP registers when native) | ||
| 744 | 20060210 | ||
| 745 | update /libmemdraw/draw.c to include 9's changes for concurrent use | ||
| 746 | remove canlock as assembly language interface, replaced by _tas | ||
| 747 | replace native use of tas by _tas; make declarations all agree | ||
| 748 | add holdon/holdoff ctl request to wm/sh | ||
| 749 | wmproxy in appl/lib/wmlib.b does not create new pgrp | ||
| 750 | 20060206 | ||
| 751 | update /appl/cmd/cp.b with digbyt's changes (mode/uid/gid correct on copied directories) | ||
| 752 | 20060203 | ||
| 753 | update /appl/cmd/ip/dhcp.b /appl/cmd/lib/dhcpclient.b | ||
| 754 | update /os/init/i4e.b to use it | ||
| 755 | add /man/8/dhcp | ||
| 756 | 20060118 | ||
| 757 | add ksize(10.1), kstrip(10.1), /utils/kstrip | ||
| 758 | new _MAGIC definitions in utils/libmach/a.out.h | ||
| 759 | 20060114 | ||
| 760 | change /os/boot/arm1110 mkfile to work on unix and windows; add to /lib/proto/os | ||
| 761 | 20060111 | ||
| 762 | -s (exportonly) -x/-y (geometry) options to 9win (TODO: rog, manual page!) | ||
| 763 | wm/sh.b: correct hold mode; remove little-used and undocumented history file | ||
| 764 | 20060109 | ||
| 765 | delete #pragma from flate.h | ||
| 766 | ensure lib9 compiles replacement sbrk for MacOSX | ||
| 767 | 20060106 | ||
| 768 | update compilers | ||
| 769 | update compilers' manual page | ||
| 770 | fix os/port/portmkfile for Plan 9: don't use $OBJDIR but Inferno/$OBJTYPE | ||
| 771 | have os/port/portmkfile check for i$CONF.p9 and use that not i$CONF for acid | ||
| 772 | add srclist(10.1) | ||
| 773 | 20060105 | ||
| 774 | account for new definition of rendezvous (void* not ulong) | ||
| 775 | add dummy setmalloctag to utils where needed (for Plan 9) | ||
| 776 | set profileflg only for ATEXT in utils/?c/txt.c | ||
| 777 | update /os/boot/pc | ||
| 778 | 20060103 | ||
| 779 | /os/ip updated from Plan 9 | ||
| 780 | /os/ip/^(bootp.c dhcp.c ihbootp.c) changed to use announce not connect for udp | ||
| 781 | 20051215 | ||
| 782 | /man/6/keytext added | ||
| 783 | 20051207 | ||
| 784 | /tools/odbc.c portability changes, and fix modes on several files | ||
| 785 | 20051202 | ||
| 786 | /emu/Plan9/devfs.c strip Inferno root from file system diagnostics | ||
| 787 | 20051130 | ||
| 788 | change /appl/svc/httpd to use lock(2) not lockprocs | ||
| 789 | 20051123 | ||
| 790 | /appl/cmd/bind.b changed not to use arg.dis, implement -q, and diagnostic change | ||
| 791 | /appl/cmd/mount.b acquired a -q option as well | ||
| 792 | 20051114 | ||
| 793 | avoid limit==0 in wm/memory.b | ||
| 794 | 20051108 | ||
| 795 | have poolmaxsize return 0 for pool of size 0 | ||
| 796 | remove /os/*/u.h (in favour of /$SYSTARG/$OBJTYPE/include/u.h) | ||
| 797 | update mkfiles accordingly | ||
| 798 | adjust mkfiles for libsec and libmp compilation for native kernels | ||
| 799 | 20051107 | ||
| 800 | added /os/manga | ||
| 801 | 20051101 | ||
| 802 | fixed /os/port/devloopback.c | ||
| 803 | updated netif.c netif.h | ||
| 804 | 20051028 | ||
| 805 | updated gettar(1) and /appl/cmd/gettar.b | ||
| 806 | 20051025 | ||
| 807 | fix British Summer Time in locales | ||
| 808 | 20051021 | ||
| 809 | updated /appl/lib/newns.b and namespace(6) for environment variable substitution | ||
| 810 | 20051018 | ||
| 811 | moved in changes from home to os/port: cis.c devbridge.c ethermii.c portclock.c devuart.c devbench.c random.c portfns.h tod.c uart.h | ||
| 812 | - mainly for changes to implement fasttick and timers | ||
| 813 | 20051017 | ||
| 814 | /limbo/ecom.c and /appl/cmd/limbo/ecom.c: ensure src set in temporary Node to avoid `no file specified' in sbl.[bc] | ||
| 815 | 20050925 | ||
| 816 | added format(2) | ||
| 817 | 20050922 | ||
| 818 | iostats(4) added | ||
| 819 | 20050919 | ||
| 820 | improve behaviour in wm/sh when in raw mode | ||
| 821 | 20050916 | ||
| 822 | /appl/lib/styx.b: return value for Rmsg.unpack for Rstat didn't include len[2] | ||
| 823 | 20050912 | ||
| 824 | update /appl/lib/disks.b, disks(2) | ||
| 825 | update /appl/cmd/disk/format.b | ||
| 826 | add /appl/cmd/disk/prep, /appl/cmd/disk/mbr.b | ||
| 827 | replace format(8) by prep(8) | ||
| 828 | delete undocumented /appl/cmd/disk/part.b | ||
| 829 | 20050908 | ||
| 830 | added disks(2) and scsiio(2) | ||
| 831 | 20050906 | ||
| 832 | os/port/devsrv.c and emu/port/devsrv.c to allow setting length by wstat (also DMAPPEND) | ||
| 833 | appl/cmd/dossrv.b fix to interpret aname:offset | ||
| 834 | usb updated to support current native uhci drivers | ||
| 835 | /appl/lib/usb/usbmass.b changed to work with new driver and more devices | ||
| 836 | 20050901 | ||
| 837 | new /appl/cmd/ip/sntp.b, sntp(8) | ||
| 838 | 20050824 | ||
| 839 | cp(1): added -gux options | ||
| 840 | 20050810 | ||
| 841 | mangaload(8): new | ||
| 842 | 20050812 | ||
| 843 | /appl/cmd/limbo/nodes.b didn't always initialise n.c (eg, a != a) | ||
| 844 | 20050712 | ||
| 845 | updated utils/[12][acl] to match Plan 9's | ||
| 846 | 20050627 | ||
| 847 | added streamcp (renamed fcp since that's what plan 9 calls a similar thing) | ||
| 848 | 20050626 | ||
| 849 | added write lock to emu/port/devip.c to stop Linux (and perhaps others) splitting socket writes by different processes | ||
| 850 | 20050620 | ||
| 851 | added w3c-xpointers(2) [/module/xpointers.m; /appl/lib/w3c/xpointers.b] | ||
| 852 | 20050617 | ||
| 853 | fixed qid array reference in /appl/cmd/lockfs.b [cjones83] | ||
| 854 | 20050610 | ||
| 855 | updated lib/ndb/dns | ||
| 856 | fixed count < 0 when reading beyond end of file in disk/kfs | ||
| 857 | 20050526 | ||
| 858 | fixed factotum's p9any to use user= attribute in key not /dev/user | ||
| 859 | fix /appl/lib/daytime.b's handling of dlpairs; also read /env/timezone if that's there | ||
| 860 | update /appl/lib/w3c/css.b to read CSS2.1 | ||
| 861 | add w3c-css(2); possibly should move module file to w3c/css.m? | ||
| 862 | 20050518 | ||
| 863 | added GPL/LGPL notice files | ||
| 864 | made single mk.b from many included source files | ||
| 865 | added MIT-template or LGPL NOTICE files to lib* directories | ||
| 866 | updated doc/port.ms | ||
| 867 | included libmp and libsec in lib/proto/src (Lucent Public License), not yet used | ||
| 868 | fix bug in cmd(3) introduced by killonclose | ||
| 869 | 20050425 | ||
| 870 | add sexprs(6) | ||
| 871 | add truerand/ntruerand and nsec[defined as osnsec] to lib9.h | ||
| 872 | redefine fmax and log2 in lib9.h | ||
| 873 | some/all FreeBSD-5.x-y don't initialise rfork_thread's procmask from parent (contrary to docs); compensate in FreeBSD/os.c | ||
| 874 | finally copy last year's changes to 1c from home | ||
| 875 | call logs->init in applylog | ||
| 876 | changed /appl/cmd/cmp.b to work correctly for differing buffer sizes, errors, etc. | ||
| 877 | included /os/pc/sd53c8xx.[in] and added /utils/na [not compiled by default] | ||
| 878 | mask off OEXCL in (emu/port os/port)^/sysfile.c:/^kcreate's openmode | ||
| 879 | wm/sh.b: keep menuitem 0 if noscroll selected | ||
| 880 | added units(1) | ||
| 881 | 20050413 | ||
| 882 | licence following MIT-template replaces `free for all' instances | ||
| 883 | "-N nice" option in os(1) | ||
| 884 | geodesy(2) is new | ||
| 885 | ebook(1) is newly released (Open Ebook browser) | ||
| 886 | wm-sh(1) has a rearranged menu, with scroll/noscroll option added | ||
| 887 | /doc/asm.ms has been updated | ||
| 888 | section 10 has been updated | ||
| 889 | limbo compiler will make simple functions inline if possible | ||
| 890 | limbo compiler supports `ref fn' type | ||
| 891 | /doc/limbo/addendum.ms [also .ps .pdf] updated to reflect `ref fn' and other changes | ||
| 892 | keyring-ipint(2) has a few new operations (shl, shr, copy) | ||
| 893 | DigestState has new copy operation replacing cloneDigestState | ||
| 894 | Keyring has new functions certtoattr, pktoattr and sktoattr each returning | ||
| 895 | a string containing attr=value ... representations of certificates and keys | ||
| 896 | u.h has been updated for all platforms, hosted and native | ||
| 897 | new ptrint, u8int, u16int, u64int, FPdbleword, and more accurate varargs for < 4 byte values | ||
| 898 | lib9.h has extra encode/decode functions moved from libcrypt | ||
| 899 | string.m has new quotec function [TODO: man page] | ||
| 900 | crypt/ssl3.b handles a particular certificate type better | ||
| 901 | charon has several bug fixes in javascript, notably parsing of certain expressions | ||
| 902 | /doc/descent/* `Descent into Limbo' updated | ||
| 903 | internally libinterp uses a different representation for parts of the linkage table | ||
| 904 | /doc/lprof.ms [also .ps and .pdf] gives overview of Limbo profiling | ||
| 905 | /doc/ebookimp.ms [also .ps and .pdf] discusses implementation of its XML browsing | ||
| 906 | /doc/compiler.ms has been updated | ||
| 907 | /doc/dis.ms eclr has been removed | ||
| 908 | emu(1) -b enables bounds checking in JIT | ||
| 909 | cs(8) handles general query (!attr=val ...) | ||
| 910 | mkfs/mkext(8) handles big archives | ||
| 911 | emuinit tries sh -c on command if not immediately dis | ||
| 912 | /appl/lib/string.b: rewritten unquoted for correct handling of embedded quotes | ||
| 913 | limbo warns about unused local variables | ||
| 914 | limbo: -F enables new implementation of function ref | ||
| 915 | limbo: -O runs optimiser | ||
| 916 | mount -9 uses 9fs not styx as service address | ||
| 917 | cmd(3) adds "killonclose" and parameter to "nice" | ||
| 918 | TODO: group check in styxserver | ||
| 919 | styxlisten accumulates algs correctly | ||
| 920 | os/port/mkdevc builds vgacursor table | ||
| 921 | touch uses OEXCL | ||
| 922 | /appl/lib/debug knows about ref fn | ||
| 923 | ecmascript: for(... in ...) parsed correctly | ||
| 924 | getuserpasswd added to factotum(2) | ||
| 925 | /appl/lib/print reincorporated | ||
| 926 | wm/clock | ||
| 927 | ftpfs calls factotum (getuserpasswd) | ||
| 928 | hoststdin/hoststdout/hoststderr [preliminary] | ||
| 929 | /os/boot/pc updated, as is its shipping list | ||
| 930 | 20041217 | ||
| 931 | base point | ||
Empty file added.
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 9 | */ | ||
| 10 | typedef struct FPU FPU; | ||
| 11 | struct FPU | ||
| 12 | { | ||
| 13 | uchar env[28]; | ||
| 14 | }; | ||
| 15 | |||
| 16 | #define KSTACK (32 * 1024) | ||
| 17 | |||
| 18 | static __inline Proc *getup(void) { | ||
| 19 | Proc *p; | ||
| 20 | __asm__( "movl %%esp, %%eax\n\t" | ||
| 21 | : "=a" (p) | ||
| 22 | ); | ||
| 23 | return *(Proc **)((unsigned long)p & ~(KSTACK - 1)); | ||
| 24 | }; | ||
| 25 | |||
| 26 | #define up (getup()) | ||
| 27 | |||
| 28 | typedef sigjmp_buf osjmpbuf; | ||
| 29 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| 30 | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Linux 386 fpu support | ||
| 3 | * Mimic Plan9 floating point support | ||
| 4 | */ | ||
| 5 | |||
| 6 | static void | ||
| 7 | setfcr(ulong fcr) | ||
| 8 | { | ||
| 9 | __asm__( "xorb $0x3f, %%al\n\t" | ||
| 10 | "pushw %%ax\n\t" | ||
| 11 | "fwait\n\t" | ||
| 12 | "fldcw (%%esp)\n\t" | ||
| 13 | "popw %%ax\n\t" | ||
| 14 | : /* no output */ | ||
| 15 | : "al" (fcr) | ||
| 16 | ); | ||
| 17 | } | ||
| 18 | |||
| 19 | static ulong | ||
| 20 | getfcr(void) | ||
| 21 | { | ||
| 22 | ulong fcr = 0; | ||
| 23 | |||
| 24 | __asm__( "pushl %%eax\n\t" | ||
| 25 | "fwait\n\t" | ||
| 26 | "fstcw (%%esp)\n\t" | ||
| 27 | "popl %%eax\n\t" | ||
| 28 | "xorb $0x3f, %%al\n\t" | ||
| 29 | : "=a" (fcr) | ||
| 30 | : "eax" (fcr) | ||
| 31 | ); | ||
| 32 | return fcr; | ||
| 33 | } | ||
| 34 | |||
| 35 | static ulong | ||
| 36 | getfsr(void) | ||
| 37 | { | ||
| 38 | ulong fsr = -1; | ||
| 39 | |||
| 40 | __asm__( "fwait\n\t" | ||
| 41 | "fstsw (%%eax)\n\t" | ||
| 42 | "movl (%%eax), %%eax\n\t" | ||
| 43 | "andl $0xffff, %%eax\n\t" | ||
| 44 | : "=a" (fsr) | ||
| 45 | : "eax" (&fsr) | ||
| 46 | ); | ||
| 47 | return fsr; | ||
| 48 | } | ||
| 49 | |||
| 50 | static void | ||
| 51 | setfsr(ulong fsr) | ||
| 52 | { | ||
| 53 | __asm__("fclex\n\t"); | ||
| 54 | } | ||
| 55 | |||
| 56 | /* FCR */ | ||
| 57 | #define FPINEX (1<<5) | ||
| 58 | #define FPUNFL ((1<<4)|(1<<1)) | ||
| 59 | #define FPOVFL (1<<3) | ||
| 60 | #define FPZDIV (1<<2) | ||
| 61 | #define FPINVAL (1<<0) | ||
| 62 | #define FPRNR (0<<10) | ||
| 63 | #define FPRZ (3<<10) | ||
| 64 | #define FPRPINF (2<<10) | ||
| 65 | #define FPRNINF (1<<10) | ||
| 66 | #define FPRMASK (3<<10) | ||
| 67 | #define FPPEXT (3<<8) | ||
| 68 | #define FPPSGL (0<<8) | ||
| 69 | #define FPPDBL (2<<8) | ||
| 70 | #define FPPMASK (3<<8) | ||
| 71 | /* FSR */ | ||
| 72 | #define FPAINEX FPINEX | ||
| 73 | #define FPAOVFL FPOVFL | ||
| 74 | #define FPAUNFL FPUNFL | ||
| 75 | #define FPAZDIV FPZDIV | ||
| 76 | #define FPAINVAL FPINVAL | ||
| @@ -0,0 +1,472 @@ | |||
| 1 | /* define _BSD_SOURCE to use ISO C, POSIX, and 4.3BSD things. */ | ||
| 2 | #ifndef _BSD_SOURCE | ||
| 3 | #define _BSD_SOURCE | ||
| 4 | #endif | ||
| 5 | /* these aren't really needed because FreeBSD does the right thing and makes off_t 64 bits, full stop */ | ||
| 6 | #define _LARGEFILE64_SOURCE 1 | ||
| 7 | #define _FILE_OFFSET_BITS 64 | ||
| 8 | #include <sys/types.h> | ||
| 9 | #include <sys/stat.h> | ||
| 10 | #include <stdlib.h> | ||
| 11 | #include <stdarg.h> | ||
| 12 | #include <unistd.h> | ||
| 13 | #include <errno.h> | ||
| 14 | #include <string.h> | ||
| 15 | #include "math.h" | ||
| 16 | #include <fcntl.h> | ||
| 17 | #include <setjmp.h> | ||
| 18 | #include <float.h> | ||
| 19 | #include <time.h> | ||
| 20 | |||
| 21 | #define getwd infgetwd | ||
| 22 | |||
| 23 | #define round infround | ||
| 24 | #define fmax inffmax | ||
| 25 | #define log2 inflog2 | ||
| 26 | |||
| 27 | #ifndef EMU | ||
| 28 | typedef struct Proc Proc; | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* | ||
| 32 | * math module dtoa | ||
| 33 | */ | ||
| 34 | #define __LITTLE_ENDIAN | ||
| 35 | |||
| 36 | #define nil ((void*)0) | ||
| 37 | |||
| 38 | typedef unsigned char uchar; | ||
| 39 | typedef signed char schar; | ||
| 40 | typedef unsigned long ulong; | ||
| 41 | typedef unsigned short Rune; | ||
| 42 | typedef long long int vlong; | ||
| 43 | typedef unsigned long long int uvlong; | ||
| 44 | typedef unsigned int u32int; | ||
| 45 | typedef uvlong u64int; | ||
| 46 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 47 | typedef unsigned short u16int; | ||
| 48 | typedef unsigned char u8int; | ||
| 49 | typedef unsigned long uintptr; | ||
| 50 | |||
| 51 | typedef signed char int8; | ||
| 52 | typedef unsigned char uint8; | ||
| 53 | typedef short int16; | ||
| 54 | typedef unsigned short uint16; | ||
| 55 | typedef int int32; | ||
| 56 | typedef unsigned int uint32; | ||
| 57 | typedef long long int64; | ||
| 58 | typedef unsigned long long uint64; | ||
| 59 | |||
| 60 | #define USED(x) if(x){}else{} | ||
| 61 | #define SET(x) | ||
| 62 | |||
| 63 | #undef nelem | ||
| 64 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 65 | #undef offsetof | ||
| 66 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 67 | #undef assert | ||
| 68 | #define assert(x) if(x){}else _assert("x") | ||
| 69 | |||
| 70 | /* | ||
| 71 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 72 | */ | ||
| 73 | |||
| 74 | extern char* strecpy(char*, char*, char*); | ||
| 75 | extern char* strdup(const char*); | ||
| 76 | extern int cistrncmp(char*, char*, int); | ||
| 77 | extern int cistrcmp(char*, char*); | ||
| 78 | extern char* cistrstr(char*, char*); | ||
| 79 | extern int tokenize(char*, char**, int); | ||
| 80 | |||
| 81 | enum | ||
| 82 | { | ||
| 83 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 84 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 85 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 86 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 87 | }; | ||
| 88 | |||
| 89 | /* | ||
| 90 | * rune routines | ||
| 91 | */ | ||
| 92 | extern int runetochar(char*, Rune*); | ||
| 93 | extern int chartorune(Rune*, char*); | ||
| 94 | extern int runelen(long); | ||
| 95 | extern int runenlen(Rune*, int); | ||
| 96 | extern int fullrune(char*, int); | ||
| 97 | extern int utflen(char*); | ||
| 98 | extern int utfnlen(char*, long); | ||
| 99 | extern char* utfrune(char*, long); | ||
| 100 | extern char* utfrrune(char*, long); | ||
| 101 | extern char* utfutf(char*, char*); | ||
| 102 | extern char* utfecpy(char*, char*, char*); | ||
| 103 | |||
| 104 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 105 | extern Rune* runestrchr(Rune*, Rune); | ||
| 106 | extern int runestrcmp(Rune*, Rune*); | ||
| 107 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 108 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 109 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 110 | extern Rune* runestrdup(Rune*); | ||
| 111 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 112 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 113 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 114 | extern long runestrlen(Rune*); | ||
| 115 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 116 | |||
| 117 | extern Rune tolowerrune(Rune); | ||
| 118 | extern Rune totitlerune(Rune); | ||
| 119 | extern Rune toupperrune(Rune); | ||
| 120 | extern int isalpharune(Rune); | ||
| 121 | extern int islowerrune(Rune); | ||
| 122 | extern int isspacerune(Rune); | ||
| 123 | extern int istitlerune(Rune); | ||
| 124 | extern int isupperrune(Rune); | ||
| 125 | |||
| 126 | /* | ||
| 127 | * malloc | ||
| 128 | */ | ||
| 129 | extern void* malloc(size_t); | ||
| 130 | extern void* mallocz(ulong, int); | ||
| 131 | extern void free(void*); | ||
| 132 | extern ulong msize(void*); | ||
| 133 | extern void* calloc(size_t, size_t); | ||
| 134 | extern void* realloc(void*, size_t); | ||
| 135 | extern void setmalloctag(void*, ulong); | ||
| 136 | extern void setrealloctag(void*, ulong); | ||
| 137 | extern ulong getmalloctag(void*); | ||
| 138 | extern ulong getrealloctag(void*); | ||
| 139 | extern void* malloctopoolblock(void*); | ||
| 140 | |||
| 141 | /* | ||
| 142 | * print routines | ||
| 143 | */ | ||
| 144 | typedef struct Fmt Fmt; | ||
| 145 | struct Fmt{ | ||
| 146 | uchar runes; /* output buffer is runes or chars? */ | ||
| 147 | void *start; /* of buffer */ | ||
| 148 | void *to; /* current place in the buffer */ | ||
| 149 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 150 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 151 | void *farg; /* to make flush a closure */ | ||
| 152 | int nfmt; /* num chars formatted so far */ | ||
| 153 | va_list args; /* args passed to dofmt */ | ||
| 154 | int r; /* % format Rune */ | ||
| 155 | int width; | ||
| 156 | int prec; | ||
| 157 | ulong flags; | ||
| 158 | }; | ||
| 159 | |||
| 160 | enum{ | ||
| 161 | FmtWidth = 1, | ||
| 162 | FmtLeft = FmtWidth << 1, | ||
| 163 | FmtPrec = FmtLeft << 1, | ||
| 164 | FmtSharp = FmtPrec << 1, | ||
| 165 | FmtSpace = FmtSharp << 1, | ||
| 166 | FmtSign = FmtSpace << 1, | ||
| 167 | FmtZero = FmtSign << 1, | ||
| 168 | FmtUnsigned = FmtZero << 1, | ||
| 169 | FmtShort = FmtUnsigned << 1, | ||
| 170 | FmtLong = FmtShort << 1, | ||
| 171 | FmtVLong = FmtLong << 1, | ||
| 172 | FmtComma = FmtVLong << 1, | ||
| 173 | FmtByte = FmtComma << 1, | ||
| 174 | |||
| 175 | FmtFlag = FmtByte << 1 | ||
| 176 | }; | ||
| 177 | |||
| 178 | extern int print(char*, ...); | ||
| 179 | extern char* seprint(char*, char*, char*, ...); | ||
| 180 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 181 | extern int snprint(char*, int, char*, ...); | ||
| 182 | extern int vsnprint(char*, int, char*, va_list); | ||
| 183 | extern char* smprint(char*, ...); | ||
| 184 | extern char* vsmprint(char*, va_list); | ||
| 185 | extern int sprint(char*, char*, ...); | ||
| 186 | extern int fprint(int, char*, ...); | ||
| 187 | extern int vfprint(int, char*, va_list); | ||
| 188 | |||
| 189 | extern int runesprint(Rune*, char*, ...); | ||
| 190 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 191 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 192 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 193 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 194 | extern Rune* runesmprint(char*, ...); | ||
| 195 | extern Rune* runevsmprint(char*, va_list); | ||
| 196 | |||
| 197 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 198 | extern int fmtfdflush(Fmt*); | ||
| 199 | extern int fmtstrinit(Fmt*); | ||
| 200 | extern char* fmtstrflush(Fmt*); | ||
| 201 | extern int runefmtstrinit(Fmt*); | ||
| 202 | extern Rune* runefmtstrflush(Fmt*); | ||
| 203 | |||
| 204 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 205 | extern int dofmt(Fmt*, char*); | ||
| 206 | extern int dorfmt(Fmt*, Rune*); | ||
| 207 | extern int fmtprint(Fmt*, char*, ...); | ||
| 208 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 209 | extern int fmtrune(Fmt*, int); | ||
| 210 | extern int fmtstrcpy(Fmt*, char*); | ||
| 211 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 212 | /* | ||
| 213 | * error string for %r | ||
| 214 | * supplied on per os basis, not part of fmt library | ||
| 215 | */ | ||
| 216 | extern int errfmt(Fmt *f); | ||
| 217 | |||
| 218 | /* | ||
| 219 | * quoted strings | ||
| 220 | */ | ||
| 221 | extern char *unquotestrdup(char*); | ||
| 222 | extern Rune *unquoterunestrdup(Rune*); | ||
| 223 | extern char *quotestrdup(char*); | ||
| 224 | extern Rune *quoterunestrdup(Rune*); | ||
| 225 | extern int quotestrfmt(Fmt*); | ||
| 226 | extern int quoterunestrfmt(Fmt*); | ||
| 227 | extern void quotefmtinstall(void); | ||
| 228 | extern int (*doquote)(int); | ||
| 229 | |||
| 230 | /* | ||
| 231 | * random number | ||
| 232 | */ | ||
| 233 | extern int nrand(int); | ||
| 234 | extern ulong truerand(void); | ||
| 235 | extern ulong ntruerand(ulong); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * math | ||
| 239 | */ | ||
| 240 | extern int isNaN(double); | ||
| 241 | extern int isInf(double, int); | ||
| 242 | extern double pow(double, double); | ||
| 243 | |||
| 244 | /* | ||
| 245 | * Time-of-day | ||
| 246 | */ | ||
| 247 | |||
| 248 | typedef struct Tm Tm; | ||
| 249 | struct Tm { | ||
| 250 | int sec; | ||
| 251 | int min; | ||
| 252 | int hour; | ||
| 253 | int mday; | ||
| 254 | int mon; | ||
| 255 | int year; | ||
| 256 | int wday; | ||
| 257 | int yday; | ||
| 258 | char zone[4]; | ||
| 259 | int tzoff; | ||
| 260 | }; | ||
| 261 | extern vlong osnsec(void); | ||
| 262 | #define nsec osnsec | ||
| 263 | |||
| 264 | /* | ||
| 265 | * one-of-a-kind | ||
| 266 | */ | ||
| 267 | extern void _assert(char*); | ||
| 268 | extern double charstod(int(*)(void*), void*); | ||
| 269 | extern char* cleanname(char*); | ||
| 270 | extern double frexp(double, int*); | ||
| 271 | extern uintptr getcallerpc(void*); | ||
| 272 | extern int getfields(char*, char**, int, int, char*); | ||
| 273 | extern char* getuser(void); | ||
| 274 | extern char* getwd(char*, int); | ||
| 275 | extern double ipow10(int); | ||
| 276 | extern double ldexp(double, int); | ||
| 277 | extern double modf(double, double*); | ||
| 278 | #define pow10 infpow10 | ||
| 279 | extern double pow10(int); | ||
| 280 | extern vlong strtoll(const char*, char**, int); | ||
| 281 | #define qsort infqsort | ||
| 282 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 283 | extern uvlong strtoull(const char*, char**, int); | ||
| 284 | extern void sysfatal(char*, ...); | ||
| 285 | extern int dec64(uchar*, int, char*, int); | ||
| 286 | extern int enc64(char*, int, uchar*, int); | ||
| 287 | extern int dec32(uchar*, int, char*, int); | ||
| 288 | extern int enc32(char*, int, uchar*, int); | ||
| 289 | extern int dec16(uchar*, int, char*, int); | ||
| 290 | extern int enc16(char*, int, uchar*, int); | ||
| 291 | extern int encodefmt(Fmt*); | ||
| 292 | |||
| 293 | /* | ||
| 294 | * synchronization | ||
| 295 | */ | ||
| 296 | typedef | ||
| 297 | struct Lock { | ||
| 298 | int val; | ||
| 299 | int pid; | ||
| 300 | } Lock; | ||
| 301 | |||
| 302 | extern int _tas(int*); | ||
| 303 | |||
| 304 | extern void lock(Lock*); | ||
| 305 | extern void unlock(Lock*); | ||
| 306 | extern int canlock(Lock*); | ||
| 307 | |||
| 308 | typedef struct QLock QLock; | ||
| 309 | struct QLock | ||
| 310 | { | ||
| 311 | Lock use; /* to access Qlock structure */ | ||
| 312 | Proc *head; /* next process waiting for object */ | ||
| 313 | Proc *tail; /* last process waiting for object */ | ||
| 314 | int locked; /* flag */ | ||
| 315 | }; | ||
| 316 | |||
| 317 | extern void qlock(QLock*); | ||
| 318 | extern void qunlock(QLock*); | ||
| 319 | extern int canqlock(QLock*); | ||
| 320 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 321 | |||
| 322 | typedef | ||
| 323 | struct RWLock | ||
| 324 | { | ||
| 325 | Lock l; /* Lock modify lock */ | ||
| 326 | QLock x; /* Mutual exclusion lock */ | ||
| 327 | QLock k; /* Lock for waiting writers */ | ||
| 328 | int readers; /* Count of readers in lock */ | ||
| 329 | } RWLock; | ||
| 330 | |||
| 331 | extern int canrlock(RWLock*); | ||
| 332 | extern int canwlock(RWLock*); | ||
| 333 | extern void rlock(RWLock*); | ||
| 334 | extern void runlock(RWLock*); | ||
| 335 | extern void wlock(RWLock*); | ||
| 336 | extern void wunlock(RWLock*); | ||
| 337 | |||
| 338 | /* | ||
| 339 | * network dialing | ||
| 340 | */ | ||
| 341 | #define NETPATHLEN 40 | ||
| 342 | |||
| 343 | /* | ||
| 344 | * system calls | ||
| 345 | * | ||
| 346 | */ | ||
| 347 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 348 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 349 | #define ERRMAX 128 /* max length of error string */ | ||
| 350 | |||
| 351 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 352 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 353 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 354 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 355 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 356 | #define MCACHE 0x0010 /* cache some data */ | ||
| 357 | #define MMASK 0x0017 /* all bits on */ | ||
| 358 | |||
| 359 | #define OREAD 0 /* open for read */ | ||
| 360 | #define OWRITE 1 /* write */ | ||
| 361 | #define ORDWR 2 /* read and write */ | ||
| 362 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 363 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 364 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 365 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 366 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 367 | |||
| 368 | #define AEXIST 0 /* accessible: exists */ | ||
| 369 | #define AEXEC 1 /* execute access */ | ||
| 370 | #define AWRITE 2 /* write access */ | ||
| 371 | #define AREAD 4 /* read access */ | ||
| 372 | |||
| 373 | /* bits in Qid.type */ | ||
| 374 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 375 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 376 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 377 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 378 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 379 | #define QTFILE 0x00 /* plain file */ | ||
| 380 | |||
| 381 | /* bits in Dir.mode */ | ||
| 382 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 383 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 384 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 385 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 386 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 387 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 388 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 389 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 390 | |||
| 391 | typedef | ||
| 392 | struct Qid | ||
| 393 | { | ||
| 394 | uvlong path; | ||
| 395 | ulong vers; | ||
| 396 | uchar type; | ||
| 397 | } Qid; | ||
| 398 | |||
| 399 | typedef | ||
| 400 | struct Dir { | ||
| 401 | /* system-modified data */ | ||
| 402 | ushort type; /* server type */ | ||
| 403 | uint dev; /* server subtype */ | ||
| 404 | /* file data */ | ||
| 405 | Qid qid; /* unique id from server */ | ||
| 406 | ulong mode; /* permissions */ | ||
| 407 | ulong atime; /* last read time */ | ||
| 408 | ulong mtime; /* last write time */ | ||
| 409 | vlong length; /* file length */ | ||
| 410 | char *name; /* last element of path */ | ||
| 411 | char *uid; /* owner name */ | ||
| 412 | char *gid; /* group name */ | ||
| 413 | char *muid; /* last modifier name */ | ||
| 414 | } Dir; | ||
| 415 | |||
| 416 | extern Dir* dirstat(char*); | ||
| 417 | extern Dir* dirfstat(int); | ||
| 418 | extern int dirwstat(char*, Dir*); | ||
| 419 | extern int dirfwstat(int, Dir*); | ||
| 420 | extern long dirread(int, Dir**); | ||
| 421 | extern void nulldir(Dir*); | ||
| 422 | extern long dirreadall(int, Dir**); | ||
| 423 | |||
| 424 | typedef | ||
| 425 | struct Waitmsg | ||
| 426 | { | ||
| 427 | int pid; /* of loved one */ | ||
| 428 | ulong time[3]; /* of loved one & descendants */ | ||
| 429 | char *msg; | ||
| 430 | } Waitmsg; | ||
| 431 | |||
| 432 | extern void _exits(char*); | ||
| 433 | |||
| 434 | extern void exits(char*); | ||
| 435 | extern int create(char*, int, int); | ||
| 436 | extern int errstr(char*, uint); | ||
| 437 | |||
| 438 | extern void perror(const char*); | ||
| 439 | extern long readn(int, void*, long); | ||
| 440 | extern int remove(const char*); | ||
| 441 | extern void rerrstr(char*, uint); | ||
| 442 | extern vlong seek(int, vlong, int); | ||
| 443 | extern int segflush(void*, ulong); | ||
| 444 | extern void werrstr(char*, ...); | ||
| 445 | |||
| 446 | extern char *argv0; | ||
| 447 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 448 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 449 | argc--, argv++) {\ | ||
| 450 | char *_args, *_argt;\ | ||
| 451 | Rune _argc;\ | ||
| 452 | _args = &argv[0][1];\ | ||
| 453 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 454 | argc--; argv++; break;\ | ||
| 455 | }\ | ||
| 456 | _argc = 0;\ | ||
| 457 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 458 | switch(_argc) | ||
| 459 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 460 | #define ARGF() (_argt=_args, _args="",\ | ||
| 461 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 462 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 463 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 464 | |||
| 465 | #define ARGC() _argc | ||
| 466 | |||
| 467 | /* | ||
| 468 | * Extensions for Inferno to basic libc.h | ||
| 469 | */ | ||
| 470 | |||
| 471 | #define setbinmode() | ||
| 472 | |||
Empty file added.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 9 | */ | ||
| 10 | typedef struct FPU FPU; | ||
| 11 | struct FPU | ||
| 12 | { | ||
| 13 | uchar env[28]; | ||
| 14 | }; | ||
| 15 | |||
| 16 | #define KSTACK (32 * 1024) | ||
| 17 | |||
| 18 | static __inline Proc *getup(void) { | ||
| 19 | Proc *p; | ||
| 20 | __asm__( "movl %%esp, %%eax\n\t" | ||
| 21 | : "=a" (p) | ||
| 22 | ); | ||
| 23 | return *(Proc **)((unsigned long)p & ~(KSTACK - 1)); | ||
| 24 | }; | ||
| 25 | |||
| 26 | #define up (getup()) | ||
| 27 | |||
| 28 | typedef sigjmp_buf osjmpbuf; | ||
| 29 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| 30 | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Linux 386 fpu support | ||
| 3 | * Mimic Plan9 floating point support | ||
| 4 | */ | ||
| 5 | |||
| 6 | static void | ||
| 7 | setfcr(ulong fcr) | ||
| 8 | { | ||
| 9 | __asm__( "xorb $0x3f, %%al\n\t" | ||
| 10 | "pushw %%ax\n\t" | ||
| 11 | "fwait\n\t" | ||
| 12 | "fldcw (%%esp)\n\t" | ||
| 13 | "popw %%ax\n\t" | ||
| 14 | : /* no output */ | ||
| 15 | : "al" (fcr) | ||
| 16 | ); | ||
| 17 | } | ||
| 18 | |||
| 19 | static ulong | ||
| 20 | getfcr(void) | ||
| 21 | { | ||
| 22 | ulong fcr = 0; | ||
| 23 | |||
| 24 | __asm__( "pushl %%eax\n\t" | ||
| 25 | "fwait\n\t" | ||
| 26 | "fstcw (%%esp)\n\t" | ||
| 27 | "popl %%eax\n\t" | ||
| 28 | "xorb $0x3f, %%al\n\t" | ||
| 29 | : "=a" (fcr) | ||
| 30 | : "eax" (fcr) | ||
| 31 | ); | ||
| 32 | return fcr; | ||
| 33 | } | ||
| 34 | |||
| 35 | static ulong | ||
| 36 | getfsr(void) | ||
| 37 | { | ||
| 38 | ulong fsr = -1; | ||
| 39 | |||
| 40 | __asm__( "fwait\n\t" | ||
| 41 | "fstsw (%%eax)\n\t" | ||
| 42 | "movl (%%eax), %%eax\n\t" | ||
| 43 | "andl $0xffff, %%eax\n\t" | ||
| 44 | : "=a" (fsr) | ||
| 45 | : "eax" (&fsr) | ||
| 46 | ); | ||
| 47 | return fsr; | ||
| 48 | } | ||
| 49 | |||
| 50 | static void | ||
| 51 | setfsr(ulong fsr) | ||
| 52 | { | ||
| 53 | __asm__("fclex\n\t"); | ||
| 54 | } | ||
| 55 | |||
| 56 | /* FCR */ | ||
| 57 | #define FPINEX (1<<5) | ||
| 58 | #define FPUNFL ((1<<4)|(1<<1)) | ||
| 59 | #define FPOVFL (1<<3) | ||
| 60 | #define FPZDIV (1<<2) | ||
| 61 | #define FPINVAL (1<<0) | ||
| 62 | #define FPRNR (0<<10) | ||
| 63 | #define FPRZ (3<<10) | ||
| 64 | #define FPRPINF (2<<10) | ||
| 65 | #define FPRNINF (1<<10) | ||
| 66 | #define FPRMASK (3<<10) | ||
| 67 | #define FPPEXT (3<<8) | ||
| 68 | #define FPPSGL (0<<8) | ||
| 69 | #define FPPDBL (2<<8) | ||
| 70 | #define FPPMASK (3<<8) | ||
| 71 | /* FSR */ | ||
| 72 | #define FPAINEX FPINEX | ||
| 73 | #define FPAOVFL FPOVFL | ||
| 74 | #define FPAUNFL FPUNFL | ||
| 75 | #define FPAZDIV FPZDIV | ||
| 76 | #define FPAINVAL FPINVAL | ||
| @@ -0,0 +1,473 @@ | |||
| 1 | /* define _BSD_SOURCE to use ISO C, POSIX, and 4.3BSD things. */ | ||
| 2 | #ifndef _BSD_SOURCE | ||
| 3 | #define _BSD_SOURCE | ||
| 4 | #endif | ||
| 5 | /* these aren't really needed because FreeBSD does the right thing and makes off_t 64 bits, full stop */ | ||
| 6 | #define _LARGEFILE64_SOURCE 1 | ||
| 7 | #define _FILE_OFFSET_BITS 64 | ||
| 8 | #include <sys/types.h> | ||
| 9 | #include <sys/stat.h> | ||
| 10 | #include <stdlib.h> | ||
| 11 | #include <stdarg.h> | ||
| 12 | #include <unistd.h> | ||
| 13 | #include <errno.h> | ||
| 14 | #include <string.h> | ||
| 15 | #include "math.h" | ||
| 16 | #include <fcntl.h> | ||
| 17 | #include <setjmp.h> | ||
| 18 | #include <float.h> | ||
| 19 | #include <time.h> | ||
| 20 | |||
| 21 | #define getwd infgetwd | ||
| 22 | |||
| 23 | #define round infround | ||
| 24 | #define fmax inffmax | ||
| 25 | #define log2 inflog2 | ||
| 26 | |||
| 27 | #ifndef EMU | ||
| 28 | typedef struct Proc Proc; | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* | ||
| 32 | * math module dtoa | ||
| 33 | */ | ||
| 34 | #define __LITTLE_ENDIAN | ||
| 35 | |||
| 36 | #define nil ((void*)0) | ||
| 37 | |||
| 38 | typedef unsigned char uchar; | ||
| 39 | typedef signed char schar; | ||
| 40 | typedef unsigned long ulong; | ||
| 41 | typedef unsigned short Rune; | ||
| 42 | typedef long long int vlong; | ||
| 43 | typedef unsigned long long int uvlong; | ||
| 44 | typedef unsigned int u32int; | ||
| 45 | typedef uvlong u64int; | ||
| 46 | |||
| 47 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 48 | typedef unsigned short u16int; | ||
| 49 | typedef unsigned char u8int; | ||
| 50 | typedef unsigned long uintptr; | ||
| 51 | |||
| 52 | typedef signed char int8; | ||
| 53 | typedef unsigned char uint8; | ||
| 54 | typedef short int16; | ||
| 55 | typedef unsigned short uint16; | ||
| 56 | typedef int int32; | ||
| 57 | typedef unsigned int uint32; | ||
| 58 | typedef long long int64; | ||
| 59 | typedef unsigned long long uint64; | ||
| 60 | |||
| 61 | #define USED(x) if(x){}else{} | ||
| 62 | #define SET(x) | ||
| 63 | |||
| 64 | #undef nelem | ||
| 65 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 66 | #undef offsetof | ||
| 67 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 68 | #undef assert | ||
| 69 | #define assert(x) if(x){}else _assert("x") | ||
| 70 | |||
| 71 | /* | ||
| 72 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 73 | */ | ||
| 74 | |||
| 75 | extern char* strecpy(char*, char*, char*); | ||
| 76 | extern char* strdup(const char*); | ||
| 77 | extern int cistrncmp(char*, char*, int); | ||
| 78 | extern int cistrcmp(char*, char*); | ||
| 79 | extern char* cistrstr(char*, char*); | ||
| 80 | extern int tokenize(char*, char**, int); | ||
| 81 | |||
| 82 | enum | ||
| 83 | { | ||
| 84 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 85 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 86 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 87 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 88 | }; | ||
| 89 | |||
| 90 | /* | ||
| 91 | * rune routines | ||
| 92 | */ | ||
| 93 | extern int runetochar(char*, Rune*); | ||
| 94 | extern int chartorune(Rune*, char*); | ||
| 95 | extern int runelen(long); | ||
| 96 | extern int runenlen(Rune*, int); | ||
| 97 | extern int fullrune(char*, int); | ||
| 98 | extern int utflen(char*); | ||
| 99 | extern int utfnlen(char*, long); | ||
| 100 | extern char* utfrune(char*, long); | ||
| 101 | extern char* utfrrune(char*, long); | ||
| 102 | extern char* utfutf(char*, char*); | ||
| 103 | extern char* utfecpy(char*, char*, char*); | ||
| 104 | |||
| 105 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 106 | extern Rune* runestrchr(Rune*, Rune); | ||
| 107 | extern int runestrcmp(Rune*, Rune*); | ||
| 108 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 109 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 110 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 111 | extern Rune* runestrdup(Rune*); | ||
| 112 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 113 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 114 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 115 | extern long runestrlen(Rune*); | ||
| 116 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 117 | |||
| 118 | extern Rune tolowerrune(Rune); | ||
| 119 | extern Rune totitlerune(Rune); | ||
| 120 | extern Rune toupperrune(Rune); | ||
| 121 | extern int isalpharune(Rune); | ||
| 122 | extern int islowerrune(Rune); | ||
| 123 | extern int isspacerune(Rune); | ||
| 124 | extern int istitlerune(Rune); | ||
| 125 | extern int isupperrune(Rune); | ||
| 126 | |||
| 127 | /* | ||
| 128 | * malloc | ||
| 129 | */ | ||
| 130 | extern void* malloc(size_t); | ||
| 131 | extern void* mallocz(ulong, int); | ||
| 132 | extern void free(void*); | ||
| 133 | extern ulong msize(void*); | ||
| 134 | extern void* calloc(size_t, size_t); | ||
| 135 | extern void* realloc(void*, size_t); | ||
| 136 | extern void setmalloctag(void*, ulong); | ||
| 137 | extern void setrealloctag(void*, ulong); | ||
| 138 | extern ulong getmalloctag(void*); | ||
| 139 | extern ulong getrealloctag(void*); | ||
| 140 | extern void* malloctopoolblock(void*); | ||
| 141 | |||
| 142 | /* | ||
| 143 | * print routines | ||
| 144 | */ | ||
| 145 | typedef struct Fmt Fmt; | ||
| 146 | struct Fmt{ | ||
| 147 | uchar runes; /* output buffer is runes or chars? */ | ||
| 148 | void *start; /* of buffer */ | ||
| 149 | void *to; /* current place in the buffer */ | ||
| 150 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 151 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 152 | void *farg; /* to make flush a closure */ | ||
| 153 | int nfmt; /* num chars formatted so far */ | ||
| 154 | va_list args; /* args passed to dofmt */ | ||
| 155 | int r; /* % format Rune */ | ||
| 156 | int width; | ||
| 157 | int prec; | ||
| 158 | ulong flags; | ||
| 159 | }; | ||
| 160 | |||
| 161 | enum{ | ||
| 162 | FmtWidth = 1, | ||
| 163 | FmtLeft = FmtWidth << 1, | ||
| 164 | FmtPrec = FmtLeft << 1, | ||
| 165 | FmtSharp = FmtPrec << 1, | ||
| 166 | FmtSpace = FmtSharp << 1, | ||
| 167 | FmtSign = FmtSpace << 1, | ||
| 168 | FmtZero = FmtSign << 1, | ||
| 169 | FmtUnsigned = FmtZero << 1, | ||
| 170 | FmtShort = FmtUnsigned << 1, | ||
| 171 | FmtLong = FmtShort << 1, | ||
| 172 | FmtVLong = FmtLong << 1, | ||
| 173 | FmtComma = FmtVLong << 1, | ||
| 174 | FmtByte = FmtComma << 1, | ||
| 175 | |||
| 176 | FmtFlag = FmtByte << 1 | ||
| 177 | }; | ||
| 178 | |||
| 179 | extern int print(char*, ...); | ||
| 180 | extern char* seprint(char*, char*, char*, ...); | ||
| 181 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 182 | extern int snprint(char*, int, char*, ...); | ||
| 183 | extern int vsnprint(char*, int, char*, va_list); | ||
| 184 | extern char* smprint(char*, ...); | ||
| 185 | extern char* vsmprint(char*, va_list); | ||
| 186 | extern int sprint(char*, char*, ...); | ||
| 187 | extern int fprint(int, char*, ...); | ||
| 188 | extern int vfprint(int, char*, va_list); | ||
| 189 | |||
| 190 | extern int runesprint(Rune*, char*, ...); | ||
| 191 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 192 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 193 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 194 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 195 | extern Rune* runesmprint(char*, ...); | ||
| 196 | extern Rune* runevsmprint(char*, va_list); | ||
| 197 | |||
| 198 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 199 | extern int fmtfdflush(Fmt*); | ||
| 200 | extern int fmtstrinit(Fmt*); | ||
| 201 | extern char* fmtstrflush(Fmt*); | ||
| 202 | extern int runefmtstrinit(Fmt*); | ||
| 203 | extern Rune* runefmtstrflush(Fmt*); | ||
| 204 | |||
| 205 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 206 | extern int dofmt(Fmt*, char*); | ||
| 207 | extern int dorfmt(Fmt*, Rune*); | ||
| 208 | extern int fmtprint(Fmt*, char*, ...); | ||
| 209 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 210 | extern int fmtrune(Fmt*, int); | ||
| 211 | extern int fmtstrcpy(Fmt*, char*); | ||
| 212 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 213 | /* | ||
| 214 | * error string for %r | ||
| 215 | * supplied on per os basis, not part of fmt library | ||
| 216 | */ | ||
| 217 | extern int errfmt(Fmt *f); | ||
| 218 | |||
| 219 | /* | ||
| 220 | * quoted strings | ||
| 221 | */ | ||
| 222 | extern char *unquotestrdup(char*); | ||
| 223 | extern Rune *unquoterunestrdup(Rune*); | ||
| 224 | extern char *quotestrdup(char*); | ||
| 225 | extern Rune *quoterunestrdup(Rune*); | ||
| 226 | extern int quotestrfmt(Fmt*); | ||
| 227 | extern int quoterunestrfmt(Fmt*); | ||
| 228 | extern void quotefmtinstall(void); | ||
| 229 | extern int (*doquote)(int); | ||
| 230 | |||
| 231 | /* | ||
| 232 | * random number | ||
| 233 | */ | ||
| 234 | extern int nrand(int); | ||
| 235 | extern ulong truerand(void); | ||
| 236 | extern ulong ntruerand(ulong); | ||
| 237 | |||
| 238 | /* | ||
| 239 | * math | ||
| 240 | */ | ||
| 241 | extern int isNaN(double); | ||
| 242 | extern int isInf(double, int); | ||
| 243 | extern double pow(double, double); | ||
| 244 | |||
| 245 | /* | ||
| 246 | * Time-of-day | ||
| 247 | */ | ||
| 248 | |||
| 249 | typedef struct Tm Tm; | ||
| 250 | struct Tm { | ||
| 251 | int sec; | ||
| 252 | int min; | ||
| 253 | int hour; | ||
| 254 | int mday; | ||
| 255 | int mon; | ||
| 256 | int year; | ||
| 257 | int wday; | ||
| 258 | int yday; | ||
| 259 | char zone[4]; | ||
| 260 | int tzoff; | ||
| 261 | }; | ||
| 262 | extern vlong osnsec(void); | ||
| 263 | #define nsec osnsec | ||
| 264 | |||
| 265 | /* | ||
| 266 | * one-of-a-kind | ||
| 267 | */ | ||
| 268 | extern void _assert(char*); | ||
| 269 | extern double charstod(int(*)(void*), void*); | ||
| 270 | extern char* cleanname(char*); | ||
| 271 | extern double frexp(double, int*); | ||
| 272 | extern uintptr getcallerpc(void*); | ||
| 273 | extern int getfields(char*, char**, int, int, char*); | ||
| 274 | extern char* getuser(void); | ||
| 275 | extern char* getwd(char*, int); | ||
| 276 | extern double ipow10(int); | ||
| 277 | extern double ldexp(double, int); | ||
| 278 | extern double modf(double, double*); | ||
| 279 | #define pow10 infpow10 | ||
| 280 | extern double pow10(int); | ||
| 281 | extern vlong strtoll(const char*, char**, int); | ||
| 282 | #define qsort infqsort | ||
| 283 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 284 | extern uvlong strtoull(const char*, char**, int); | ||
| 285 | extern void sysfatal(char*, ...); | ||
| 286 | extern int dec64(uchar*, int, char*, int); | ||
| 287 | extern int enc64(char*, int, uchar*, int); | ||
| 288 | extern int dec32(uchar*, int, char*, int); | ||
| 289 | extern int enc32(char*, int, uchar*, int); | ||
| 290 | extern int dec16(uchar*, int, char*, int); | ||
| 291 | extern int enc16(char*, int, uchar*, int); | ||
| 292 | extern int encodefmt(Fmt*); | ||
| 293 | |||
| 294 | /* | ||
| 295 | * synchronization | ||
| 296 | */ | ||
| 297 | typedef | ||
| 298 | struct Lock { | ||
| 299 | int val; | ||
| 300 | int pid; | ||
| 301 | } Lock; | ||
| 302 | |||
| 303 | extern int _tas(int*); | ||
| 304 | |||
| 305 | extern void lock(Lock*); | ||
| 306 | extern void unlock(Lock*); | ||
| 307 | extern int canlock(Lock*); | ||
| 308 | |||
| 309 | typedef struct QLock QLock; | ||
| 310 | struct QLock | ||
| 311 | { | ||
| 312 | Lock use; /* to access Qlock structure */ | ||
| 313 | Proc *head; /* next process waiting for object */ | ||
| 314 | Proc *tail; /* last process waiting for object */ | ||
| 315 | int locked; /* flag */ | ||
| 316 | }; | ||
| 317 | |||
| 318 | extern void qlock(QLock*); | ||
| 319 | extern void qunlock(QLock*); | ||
| 320 | extern int canqlock(QLock*); | ||
| 321 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 322 | |||
| 323 | typedef | ||
| 324 | struct RWLock | ||
| 325 | { | ||
| 326 | Lock l; /* Lock modify lock */ | ||
| 327 | QLock x; /* Mutual exclusion lock */ | ||
| 328 | QLock k; /* Lock for waiting writers */ | ||
| 329 | int readers; /* Count of readers in lock */ | ||
| 330 | } RWLock; | ||
| 331 | |||
| 332 | extern int canrlock(RWLock*); | ||
| 333 | extern int canwlock(RWLock*); | ||
| 334 | extern void rlock(RWLock*); | ||
| 335 | extern void runlock(RWLock*); | ||
| 336 | extern void wlock(RWLock*); | ||
| 337 | extern void wunlock(RWLock*); | ||
| 338 | |||
| 339 | /* | ||
| 340 | * network dialing | ||
| 341 | */ | ||
| 342 | #define NETPATHLEN 40 | ||
| 343 | |||
| 344 | /* | ||
| 345 | * system calls | ||
| 346 | * | ||
| 347 | */ | ||
| 348 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 349 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 350 | #define ERRMAX 128 /* max length of error string */ | ||
| 351 | |||
| 352 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 353 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 354 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 355 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 356 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 357 | #define MCACHE 0x0010 /* cache some data */ | ||
| 358 | #define MMASK 0x0017 /* all bits on */ | ||
| 359 | |||
| 360 | #define OREAD 0 /* open for read */ | ||
| 361 | #define OWRITE 1 /* write */ | ||
| 362 | #define ORDWR 2 /* read and write */ | ||
| 363 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 364 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 365 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 366 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 367 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 368 | |||
| 369 | #define AEXIST 0 /* accessible: exists */ | ||
| 370 | #define AEXEC 1 /* execute access */ | ||
| 371 | #define AWRITE 2 /* write access */ | ||
| 372 | #define AREAD 4 /* read access */ | ||
| 373 | |||
| 374 | /* bits in Qid.type */ | ||
| 375 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 376 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 377 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 378 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 379 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 380 | #define QTFILE 0x00 /* plain file */ | ||
| 381 | |||
| 382 | /* bits in Dir.mode */ | ||
| 383 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 384 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 385 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 386 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 387 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 388 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 389 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 390 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 391 | |||
| 392 | typedef | ||
| 393 | struct Qid | ||
| 394 | { | ||
| 395 | uvlong path; | ||
| 396 | ulong vers; | ||
| 397 | uchar type; | ||
| 398 | } Qid; | ||
| 399 | |||
| 400 | typedef | ||
| 401 | struct Dir { | ||
| 402 | /* system-modified data */ | ||
| 403 | ushort type; /* server type */ | ||
| 404 | uint dev; /* server subtype */ | ||
| 405 | /* file data */ | ||
| 406 | Qid qid; /* unique id from server */ | ||
| 407 | ulong mode; /* permissions */ | ||
| 408 | ulong atime; /* last read time */ | ||
| 409 | ulong mtime; /* last write time */ | ||
| 410 | vlong length; /* file length */ | ||
| 411 | char *name; /* last element of path */ | ||
| 412 | char *uid; /* owner name */ | ||
| 413 | char *gid; /* group name */ | ||
| 414 | char *muid; /* last modifier name */ | ||
| 415 | } Dir; | ||
| 416 | |||
| 417 | extern Dir* dirstat(char*); | ||
| 418 | extern Dir* dirfstat(int); | ||
| 419 | extern int dirwstat(char*, Dir*); | ||
| 420 | extern int dirfwstat(int, Dir*); | ||
| 421 | extern long dirread(int, Dir**); | ||
| 422 | extern void nulldir(Dir*); | ||
| 423 | extern long dirreadall(int, Dir**); | ||
| 424 | |||
| 425 | typedef | ||
| 426 | struct Waitmsg | ||
| 427 | { | ||
| 428 | int pid; /* of loved one */ | ||
| 429 | ulong time[3]; /* of loved one & descendants */ | ||
| 430 | char *msg; | ||
| 431 | } Waitmsg; | ||
| 432 | |||
| 433 | extern void _exits(char*); | ||
| 434 | |||
| 435 | extern void exits(char*); | ||
| 436 | extern int create(char*, int, int); | ||
| 437 | extern int errstr(char*, uint); | ||
| 438 | |||
| 439 | extern void perror(const char*); | ||
| 440 | extern long readn(int, void*, long); | ||
| 441 | extern int remove(const char*); | ||
| 442 | extern void rerrstr(char*, uint); | ||
| 443 | extern vlong seek(int, vlong, int); | ||
| 444 | extern int segflush(void*, ulong); | ||
| 445 | extern void werrstr(char*, ...); | ||
| 446 | |||
| 447 | extern char *argv0; | ||
| 448 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 449 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 450 | argc--, argv++) {\ | ||
| 451 | char *_args, *_argt;\ | ||
| 452 | Rune _argc;\ | ||
| 453 | _args = &argv[0][1];\ | ||
| 454 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 455 | argc--; argv++; break;\ | ||
| 456 | }\ | ||
| 457 | _argc = 0;\ | ||
| 458 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 459 | switch(_argc) | ||
| 460 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 461 | #define ARGF() (_argt=_args, _args="",\ | ||
| 462 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 463 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 464 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 465 | |||
| 466 | #define ARGC() _argc | ||
| 467 | |||
| 468 | /* | ||
| 469 | * Extensions for Inferno to basic libc.h | ||
| 470 | */ | ||
| 471 | |||
| 472 | #define setbinmode() | ||
| 473 | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc* getup(); | ||
| 8 | #define up (getup()) | ||
| 9 | |||
| 10 | /* | ||
| 11 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 12 | */ | ||
| 13 | typedef struct FPU FPU; | ||
| 14 | struct FPU | ||
| 15 | { | ||
| 16 | fp_control fsr; | ||
| 17 | }; | ||
| 18 | |||
| 19 | typedef sigjmp_buf osjmpbuf; | ||
| 20 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| 21 | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | Installing hosted Inferno from source | ||
| 2 | |||
| 3 | Overview | ||
| 4 | |||
| 5 | Like the native kernels emu relies on several auxil- | ||
| 6 | iary libraries (the source of which it often shares with the | ||
| 7 | native kernels). Emu itself is built by the mkfile in the | ||
| 8 | emu subdirectory containing the platform-specific source for | ||
| 9 | the host platform. Each library has its own mkfile; the | ||
| 10 | various components are made in the right order by the | ||
| 11 | mkfile at the root of the Inferno tree. The mkfile for | ||
| 12 | each platform will also invoke mk recursively to make the | ||
| 13 | appropriate libraries for a given configuration. | ||
| 14 | |||
| 15 | The Unix emu variant generally is covered by `POSIX' | ||
| 16 | (with common extensions) but each Unix port has one file | ||
| 17 | that differs considerably for each port, namely | ||
| 18 | emu/platform/os.c, the differences corresponding to the dif- | ||
| 19 | ferent ways under Unix of implementing kernel-scheduled | ||
| 20 | threads efficiently. | ||
| 21 | |||
| 22 | There are working emu versions for FreeBSD/386, | ||
| 23 | Irix/mips, Linux/386, NetBSD/386, MacOSX/386, MacOSX/power, | ||
| 24 | Plan 9, Solaris/sparc, and Windows (NT, 2000 and Explorer | ||
| 25 | plug-in). Each platform typically uses mechanisms specific | ||
| 26 | to the host operating system to implement Inferno's internal | ||
| 27 | thread/process structure. POSIX threads have often been | ||
| 28 | found to be insufficient (poorly implemented) on some plat- | ||
| 29 | forms, and if so are avoided. See kproc in emu/*/os.c. | ||
| 30 | |||
| 31 | Source is included for ports to HP/UX (S800 architec- | ||
| 32 | ture), Solaris/386, and Unixware, in case someone wishes to | ||
| 33 | take them up now, but we have not determined their fitness. | ||
| 34 | |||
| 35 | The Plan 9 hosted implementation is unusual in that it | ||
| 36 | supports several processor types: 386, mips, power (Power | ||
| 37 | PC) and sparc. Furthermore, all versions of emu can be | ||
| 38 | built on any processor type, in the usual way for Plan 9. | ||
| 39 | |||
| 40 | Otherwise, as distributed, emu for a platform can only | ||
| 41 | be built when running on that platform. | ||
| 42 | |||
| 43 | One unusual variant makes the whole of Inferno a plug- | ||
| 44 | in for Microsoft's Internet Explorer, giving the same envi- | ||
| 45 | ronment for Inferno applications running in an HTML page as | ||
| 46 | is provided by hosted or native Inferno. That is, there is | ||
| 47 | not a distinct `applet' environment with special programming | ||
| 48 | interfaces. The source for the various plug-in components | ||
| 49 | is found in /tools/plugin and /usr/internet within the | ||
| 50 | Inferno tree; they use the version of emu defined by the | ||
| 51 | configuration file /emu/Nt/ie. | ||
| 52 | |||
| 53 | Build steps | ||
| 54 | |||
| 55 | All the libraries and executables can be built in a | ||
| 56 | tree containing only the source code. To do that for a sup- | ||
| 57 | ported variant of hosted Inferno, on Unix or Plan 9, do the | ||
| 58 | following in the root of the Inferno tree: | ||
| 59 | |||
| 60 | 1 Edit mkconfig to reflect your host environment, | ||
| 61 | specifically ROOT (which must be an absolute path | ||
| 62 | name), SYSHOST and OBJTYPE. The comments in the file | ||
| 63 | should help you choose. | ||
| 64 | |||
| 65 | 2 Run makemk.sh to rebuild the mk command, which is | ||
| 66 | used to build everything else. | ||
| 67 | |||
| 68 | 3 Set PATH (or path on Plan 9) to include the bin | ||
| 69 | directory for the platform, which will now contain the | ||
| 70 | mk binary just built. On Unix, export PATH. | ||
| 71 | |||
| 72 | 4 Then mk nuke to remove any extraneous object files. | ||
| 73 | |||
| 74 | 5 Finally, mk install to create and install the | ||
| 75 | libraries, limbo compiler, emu for hosted Inferno, | ||
| 76 | and auxiliary commands. The rules do that in an order | ||
| 77 | that ensures that the commands or libraries needed by a | ||
| 78 | later stage are built and installed first. (Note that | ||
| 79 | a plain mk will not suffice, because it does not put | ||
| 80 | the results in the search path.) | ||
| 81 | |||
| 82 | Doing something similar on Windows or Plan 9 currently | ||
| 83 | requires the executable for mk to be available in the | ||
| 84 | search path, since there is no equivalent of makemk.sh. | ||
| 85 | Otherwise the procedure is the same. On Plan 9, of course, | ||
| 86 | the host system's normal version of mk should be adequate. | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | #include <u.h> | ||
| 2 | #include <kern.h> | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Extensions for Inferno to basic libc.h | ||
| 6 | */ | ||
| 7 | |||
| 8 | #define __LITTLE_ENDIAN /* math/dtoa.c only */ | ||
| @@ -0,0 +1,64 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | typedef unsigned short ushort; | ||
| 3 | typedef unsigned char uchar; | ||
| 4 | typedef unsigned long ulong; | ||
| 5 | typedef unsigned int uint; | ||
| 6 | typedef signed char schar; | ||
| 7 | typedef long long vlong; | ||
| 8 | typedef unsigned long long uvlong; | ||
| 9 | typedef unsigned long uintptr; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC 0 | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | |||
| 22 | /* FCR */ | ||
| 23 | #define FPINEX (1<<5) | ||
| 24 | #define FPUNFL ((1<<4)|(1<<1)) | ||
| 25 | #define FPOVFL (1<<3) | ||
| 26 | #define FPZDIV (1<<2) | ||
| 27 | #define FPINVAL (1<<0) | ||
| 28 | #define FPRNR (0<<10) | ||
| 29 | #define FPRZ (3<<10) | ||
| 30 | #define FPRPINF (2<<10) | ||
| 31 | #define FPRNINF (1<<10) | ||
| 32 | #define FPRMASK (3<<10) | ||
| 33 | #define FPPEXT (3<<8) | ||
| 34 | #define FPPSGL (0<<8) | ||
| 35 | #define FPPDBL (2<<8) | ||
| 36 | #define FPPMASK (3<<8) | ||
| 37 | /* FSR */ | ||
| 38 | #define FPAINEX FPINEX | ||
| 39 | #define FPAOVFL FPOVFL | ||
| 40 | #define FPAUNFL FPUNFL | ||
| 41 | #define FPAZDIV FPZDIV | ||
| 42 | #define FPAINVAL FPINVAL | ||
| 43 | union FPdbleword | ||
| 44 | { | ||
| 45 | double x; | ||
| 46 | struct { /* little endian */ | ||
| 47 | ulong lo; | ||
| 48 | ulong hi; | ||
| 49 | }; | ||
| 50 | }; | ||
| 51 | |||
| 52 | typedef char* va_list; | ||
| 53 | #define va_start(list, start) list =\ | ||
| 54 | (sizeof(start) < 4?\ | ||
| 55 | (char*)((int*)&(start)+1):\ | ||
| 56 | (char*)(&(start)+1)) | ||
| 57 | #define va_end(list)\ | ||
| 58 | USED(list) | ||
| 59 | #define va_arg(list, mode)\ | ||
| 60 | ((sizeof(mode) == 1)?\ | ||
| 61 | ((mode*)(list += 4))[-4]:\ | ||
| 62 | (sizeof(mode) == 2)?\ | ||
| 63 | ((mode*)(list += 4))[-2]:\ | ||
| 64 | ((mode*)(list += sizeof(mode)))[-1]) | ||
| @@ -0,0 +1,25 @@ | |||
| 1 | struct Ureg | ||
| 2 | { | ||
| 3 | ulong di; /* general registers */ | ||
| 4 | ulong si; /* ... */ | ||
| 5 | ulong bp; /* ... */ | ||
| 6 | ulong nsp; | ||
| 7 | ulong bx; /* ... */ | ||
| 8 | ulong dx; /* ... */ | ||
| 9 | ulong cx; /* ... */ | ||
| 10 | ulong ax; /* ... */ | ||
| 11 | ulong gs; /* data segments */ | ||
| 12 | ulong fs; /* ... */ | ||
| 13 | ulong es; /* ... */ | ||
| 14 | ulong ds; /* ... */ | ||
| 15 | ulong trap; /* trap type */ | ||
| 16 | ulong ecode; /* error code (or zero) */ | ||
| 17 | ulong pc; /* pc */ | ||
| 18 | ulong cs; /* old context */ | ||
| 19 | ulong flags; /* old flags */ | ||
| 20 | union { | ||
| 21 | ulong usp; | ||
| 22 | ulong sp; | ||
| 23 | }; | ||
| 24 | ulong ss; /* old stack segment */ | ||
| 25 | }; | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | #include <u.h> | ||
| 2 | #include <kern.h> | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Extensions for Inferno to basic libc.h | ||
| 6 | */ | ||
| 7 | |||
| 8 | #define __LITTLE_ENDIAN /* math/dtoa.c; longs in ARM doubles are big-endian */ | ||
| @@ -0,0 +1,65 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | |||
| 3 | typedef unsigned short ushort; | ||
| 4 | typedef unsigned char uchar; | ||
| 5 | typedef unsigned long ulong; | ||
| 6 | typedef unsigned int uint; | ||
| 7 | typedef signed char schar; | ||
| 8 | typedef long long vlong; | ||
| 9 | typedef unsigned long long uvlong; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC 0 | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | typedef unsigned long uintptr; | ||
| 22 | |||
| 23 | /* FCR */ | ||
| 24 | #define FPINEX (1<<20) | ||
| 25 | #define FPUNFL (1<<19) | ||
| 26 | #define FPOVFL (1<<18) | ||
| 27 | #define FPZDIV (1<<17) | ||
| 28 | #define FPINVAL (1<<16) | ||
| 29 | #define FPRNR (0<<0) | ||
| 30 | #define FPRZ (1<<0) | ||
| 31 | #define FPRPINF (2<<0) | ||
| 32 | #define FPRNINF (3<<0) | ||
| 33 | #define FPRMASK (3<<0) | ||
| 34 | #define FPPEXT 0 | ||
| 35 | #define FPPSGL 0 | ||
| 36 | #define FPPDBL 0 | ||
| 37 | #define FPPMASK 0 | ||
| 38 | /* FSR */ | ||
| 39 | #define FPAINEX (1<<4) | ||
| 40 | #define FPAUNFL (1<<3) | ||
| 41 | #define FPAOVFL (1<<2) | ||
| 42 | #define FPAZDIV (1<<1) | ||
| 43 | #define FPAINVAL (1<<0) | ||
| 44 | union FPdbleword | ||
| 45 | { | ||
| 46 | double x; | ||
| 47 | struct { /* little endian (on VFP and now in software) */ | ||
| 48 | ulong lo; | ||
| 49 | ulong hi; | ||
| 50 | }; | ||
| 51 | }; | ||
| 52 | |||
| 53 | typedef char* va_list; | ||
| 54 | #define va_start(list, start) list =\ | ||
| 55 | (sizeof(start) < 4?\ | ||
| 56 | (char*)((int*)&(start)+1):\ | ||
| 57 | (char*)(&(start)+1)) | ||
| 58 | #define va_end(list)\ | ||
| 59 | USED(list) | ||
| 60 | #define va_arg(list, mode)\ | ||
| 61 | ((sizeof(mode) == 1)?\ | ||
| 62 | ((mode*)(list += 4))[-4]:\ | ||
| 63 | (sizeof(mode) == 2)?\ | ||
| 64 | ((mode*)(list += 4))[-2]:\ | ||
| 65 | ((mode*)(list += sizeof(mode)))[-1]) | ||
| @@ -0,0 +1,24 @@ | |||
| 1 | typedef struct Ureg { | ||
| 2 | uint r0; | ||
| 3 | uint r1; | ||
| 4 | uint r2; | ||
| 5 | uint r3; | ||
| 6 | uint r4; | ||
| 7 | uint r5; | ||
| 8 | uint r6; | ||
| 9 | uint r7; | ||
| 10 | uint r8; | ||
| 11 | uint r9; | ||
| 12 | uint r10; | ||
| 13 | uint r11; | ||
| 14 | uint r12; | ||
| 15 | union { | ||
| 16 | uint r13; | ||
| 17 | uint sp; | ||
| 18 | }; | ||
| 19 | uint r14; | ||
| 20 | uint link; | ||
| 21 | uint type; | ||
| 22 | uint psr; | ||
| 23 | uint pc; | ||
| 24 | } Ureg; | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | #include <u.h> | ||
| 2 | #include <kern.h> | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Extensions for Inferno to basic libc.h | ||
| 6 | */ | ||
| 7 | |||
| 8 | #undef __LITTLE_ENDIAN /* math/dtoa.c; longs in MIPS doubles are big-endian */ | ||
| @@ -0,0 +1,65 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | typedef unsigned short ushort; | ||
| 3 | typedef unsigned char uchar; | ||
| 4 | typedef unsigned long ulong; | ||
| 5 | typedef unsigned int uint; | ||
| 6 | typedef signed char schar; | ||
| 7 | typedef long long vlong; | ||
| 8 | typedef unsigned long long uvlong; | ||
| 9 | typedef unsigned long uintptr; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC 0 | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | |||
| 22 | /* FCR */ | ||
| 23 | #define FPINEX (1<<7) | ||
| 24 | #define FPUNFL (1<<8) | ||
| 25 | #define FPOVFL (1<<9) | ||
| 26 | #define FPZDIV (1<<10) | ||
| 27 | #define FPINVAL (1<<11) | ||
| 28 | #define FPRNR (0<<0) | ||
| 29 | #define FPRZ (1<<0) | ||
| 30 | #define FPRPINF (2<<0) | ||
| 31 | #define FPRNINF (3<<0) | ||
| 32 | #define FPRMASK (3<<0) | ||
| 33 | #define FPPEXT 0 | ||
| 34 | #define FPPSGL 0 | ||
| 35 | #define FPPDBL 0 | ||
| 36 | #define FPPMASK 0 | ||
| 37 | /* FSR */ | ||
| 38 | #define FPAINEX (1<<2) | ||
| 39 | #define FPAOVFL (1<<4) | ||
| 40 | #define FPAUNFL (1<<3) | ||
| 41 | #define FPAZDIV (1<<5) | ||
| 42 | #define FPAINVAL (1<<6) | ||
| 43 | union FPdbleword | ||
| 44 | { | ||
| 45 | double x; | ||
| 46 | struct { /* big endian */ | ||
| 47 | ulong hi; | ||
| 48 | ulong lo; | ||
| 49 | }; | ||
| 50 | }; | ||
| 51 | |||
| 52 | /* stdarg */ | ||
| 53 | typedef char* va_list; | ||
| 54 | #define va_start(list, start) list =\ | ||
| 55 | (sizeof(start) < 4?\ | ||
| 56 | (char*)((int*)&(start)+1):\ | ||
| 57 | (char*)(&(start)+1)) | ||
| 58 | #define va_end(list)\ | ||
| 59 | USED(list) | ||
| 60 | #define va_arg(list, mode)\ | ||
| 61 | ((sizeof(mode) == 1)?\ | ||
| 62 | ((mode*)(list += 4))[-1]:\ | ||
| 63 | (sizeof(mode) == 2)?\ | ||
| 64 | ((mode*)(list += 4))[-1]:\ | ||
| 65 | ((mode*)(list += sizeof(mode)))[-1]) | ||
| @@ -0,0 +1,4 @@ | |||
| 1 | #include <u.h> | ||
| 2 | #include <kern.h> | ||
| 3 | |||
| 4 | #undef __LITTLE_ENDIAN /* math/dtoa.c; longs in PowerPC doubles are big-endian */ | ||
| @@ -0,0 +1,84 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | typedef unsigned short ushort; | ||
| 3 | typedef unsigned char uchar; | ||
| 4 | typedef unsigned long ulong; | ||
| 5 | typedef unsigned int uint; | ||
| 6 | typedef signed char schar; | ||
| 7 | typedef long long vlong; | ||
| 8 | typedef unsigned long long uvlong; | ||
| 9 | typedef unsigned long uintptr; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC 0 | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | |||
| 22 | /* FPSCR */ | ||
| 23 | #define FPSFX (1<<31) /* exception summary (sticky) */ | ||
| 24 | #define FPSEX (1<<30) /* enabled exception summary */ | ||
| 25 | #define FPSVX (1<<29) /* invalid operation exception summary */ | ||
| 26 | #define FPSOX (1<<28) /* overflow exception OX (sticky) */ | ||
| 27 | #define FPSUX (1<<27) /* underflow exception UX (sticky) */ | ||
| 28 | #define FPSZX (1<<26) /* zero divide exception ZX (sticky) */ | ||
| 29 | #define FPSXX (1<<25) /* inexact exception XX (sticky) */ | ||
| 30 | #define FPSVXSNAN (1<<24) /* invalid operation exception for SNaN (sticky) */ | ||
| 31 | #define FPSVXISI (1<<23) /* invalid operation exception for ∞-∞ (sticky) */ | ||
| 32 | #define FPSVXIDI (1<<22) /* invalid operation exception for ∞/∞ (sticky) */ | ||
| 33 | #define FPSVXZDZ (1<<21) /* invalid operation exception for 0/0 (sticky) */ | ||
| 34 | #define FPSVXIMZ (1<<20) /* invalid operation exception for ∞*0 (sticky) */ | ||
| 35 | #define FPSVXVC (1<<19) /* invalid operation exception for invalid compare (sticky) */ | ||
| 36 | #define FPSFR (1<<18) /* fraction rounded */ | ||
| 37 | #define FPSFI (1<<17) /* fraction inexact */ | ||
| 38 | #define FPSFPRF (1<<16) /* floating point result class */ | ||
| 39 | #define FPSFPCC (0xF<<12) /* <, >, =, unordered */ | ||
| 40 | #define FPVXCVI (1<<8) /* enable exception for invalid integer convert (sticky) */ | ||
| 41 | #define FPVE (1<<7) /* invalid operation exception enable */ | ||
| 42 | #define FPOVFL (1<<6) /* enable overflow exceptions */ | ||
| 43 | #define FPUNFL (1<<5) /* enable underflow */ | ||
| 44 | #define FPZDIV (1<<4) /* enable zero divide */ | ||
| 45 | #define FPINEX (1<<3) /* enable inexact exceptions */ | ||
| 46 | #define FPRMASK (3<<0) /* rounding mode */ | ||
| 47 | #define FPRNR (0<<0) | ||
| 48 | #define FPRZ (1<<0) | ||
| 49 | #define FPRPINF (2<<0) | ||
| 50 | #define FPRNINF (3<<0) | ||
| 51 | #define FPPEXT 0 | ||
| 52 | #define FPPSGL 0 | ||
| 53 | #define FPPDBL 0 | ||
| 54 | #define FPPMASK 0 | ||
| 55 | #define FPINVAL FPVE | ||
| 56 | |||
| 57 | #define FPAOVFL FPSOX | ||
| 58 | #define FPAINEX FPSXX | ||
| 59 | #define FPAUNFL FPSUX | ||
| 60 | #define FPAZDIV FPSZX | ||
| 61 | #define FPAINVAL FPSVX | ||
| 62 | |||
| 63 | union FPdbleword | ||
| 64 | { | ||
| 65 | double x; | ||
| 66 | struct { /* big endian */ | ||
| 67 | ulong hi; | ||
| 68 | ulong lo; | ||
| 69 | }; | ||
| 70 | }; | ||
| 71 | |||
| 72 | typedef char* va_list; | ||
| 73 | #define va_start(list, start) list =\ | ||
| 74 | (sizeof(start) < 4?\ | ||
| 75 | (char*)((int*)&(start)+1):\ | ||
| 76 | (char*)(&(start)+1)) | ||
| 77 | #define va_end(list)\ | ||
| 78 | USED(list) | ||
| 79 | #define va_arg(list, mode)\ | ||
| 80 | ((sizeof(mode) == 1)?\ | ||
| 81 | ((mode*)(list += 4))[-1]:\ | ||
| 82 | (sizeof(mode) == 2)?\ | ||
| 83 | ((mode*)(list += 4))[-1]:\ | ||
| 84 | ((mode*)(list += sizeof(mode)))[-1]) | ||
| @@ -0,0 +1,43 @@ | |||
| 1 | struct Ureg | ||
| 2 | { | ||
| 3 | ulong cause; | ||
| 4 | union { ulong srr1; ulong status;}; | ||
| 5 | ulong pc; /* SRR0 */ | ||
| 6 | ulong pad; | ||
| 7 | ulong lr; | ||
| 8 | ulong cr; | ||
| 9 | ulong xer; | ||
| 10 | ulong ctr; | ||
| 11 | ulong r0; | ||
| 12 | union{ ulong r1; ulong sp; ulong usp; }; | ||
| 13 | ulong r2; | ||
| 14 | ulong r3; | ||
| 15 | ulong r4; | ||
| 16 | ulong r5; | ||
| 17 | ulong r6; | ||
| 18 | ulong r7; | ||
| 19 | ulong r8; | ||
| 20 | ulong r9; | ||
| 21 | ulong r10; | ||
| 22 | ulong r11; | ||
| 23 | ulong r12; | ||
| 24 | ulong r13; | ||
| 25 | ulong r14; | ||
| 26 | ulong r15; | ||
| 27 | ulong r16; | ||
| 28 | ulong r17; | ||
| 29 | ulong r18; | ||
| 30 | ulong r19; | ||
| 31 | ulong r20; | ||
| 32 | ulong r21; | ||
| 33 | ulong r22; | ||
| 34 | ulong r23; | ||
| 35 | ulong r24; | ||
| 36 | ulong r25; | ||
| 37 | ulong r26; | ||
| 38 | ulong r27; | ||
| 39 | ulong r28; | ||
| 40 | ulong r29; | ||
| 41 | ulong r30; | ||
| 42 | ulong r31; | ||
| 43 | }; | ||
| @@ -0,0 +1,9 @@ | |||
| 1 | #include <u.h> | ||
| 2 | #include <kern.h> | ||
| 3 | |||
| 4 | |||
| 5 | /* | ||
| 6 | * Extensions for Inferno to basic libc.h | ||
| 7 | */ | ||
| 8 | |||
| 9 | #undef __LITTLE_ENDIAN /* math/dtoa.c; longs in SPARC doubles are big-endian */ | ||
| @@ -0,0 +1,64 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | typedef unsigned short ushort; | ||
| 3 | typedef unsigned char uchar; | ||
| 4 | typedef unsigned long ulong; | ||
| 5 | typedef unsigned int uint; | ||
| 6 | typedef signed char schar; | ||
| 7 | typedef long long vlong; | ||
| 8 | typedef unsigned long long uvlong; | ||
| 9 | typedef unsigned long uintptr; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC (-8) | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | |||
| 22 | /* FCR */ | ||
| 23 | #define FPINEX (1<<23) | ||
| 24 | #define FPOVFL (1<<26) | ||
| 25 | #define FPUNFL (1<<25) | ||
| 26 | #define FPZDIV (1<<24) | ||
| 27 | #define FPRNR (0<<30) | ||
| 28 | #define FPRZ (1<<30) | ||
| 29 | #define FPINVAL (1<<27) | ||
| 30 | #define FPRPINF (2<<30) | ||
| 31 | #define FPRNINF (3<<30) | ||
| 32 | #define FPRMASK (3<<30) | ||
| 33 | #define FPPEXT 0 | ||
| 34 | #define FPPSGL 0 | ||
| 35 | #define FPPDBL 0 | ||
| 36 | #define FPPMASK 0 | ||
| 37 | /* FSR */ | ||
| 38 | #define FPAINEX (1<<5) | ||
| 39 | #define FPAZDIV (1<<6) | ||
| 40 | #define FPAUNFL (1<<7) | ||
| 41 | #define FPAOVFL (1<<8) | ||
| 42 | #define FPAINVAL (1<<9) | ||
| 43 | union FPdbleword | ||
| 44 | { | ||
| 45 | double x; | ||
| 46 | struct { /* big endian */ | ||
| 47 | ulong hi; | ||
| 48 | ulong lo; | ||
| 49 | }; | ||
| 50 | }; | ||
| 51 | |||
| 52 | typedef char* va_list; | ||
| 53 | #define va_start(list, start) list =\ | ||
| 54 | (sizeof(start) < 4?\ | ||
| 55 | (char*)((int*)&(start)+1):\ | ||
| 56 | (char*)(&(start)+1)) | ||
| 57 | #define va_end(list)\ | ||
| 58 | USED(list) | ||
| 59 | #define va_arg(list, mode)\ | ||
| 60 | ((sizeof(mode) == 1)?\ | ||
| 61 | ((mode*)(list += 4))[-1]:\ | ||
| 62 | (sizeof(mode) == 2)?\ | ||
| 63 | ((mode*)(list += 4))[-1]:\ | ||
| 64 | ((mode*)(list += sizeof(mode)))[-1]) | ||
| @@ -0,0 +1,45 @@ | |||
| 1 | struct Ureg | ||
| 2 | { | ||
| 3 | ulong r0; /* unnecessary; just for symmetry */ | ||
| 4 | union{ | ||
| 5 | ulong sp; /* r1 */ | ||
| 6 | ulong usp; /* r1 */ | ||
| 7 | ulong r1; | ||
| 8 | }; | ||
| 9 | ulong r2; | ||
| 10 | ulong r3; | ||
| 11 | ulong r4; | ||
| 12 | ulong r5; | ||
| 13 | ulong r6; | ||
| 14 | ulong r7; | ||
| 15 | ulong r8; | ||
| 16 | ulong r9; | ||
| 17 | ulong r10; | ||
| 18 | ulong r11; | ||
| 19 | ulong r12; | ||
| 20 | ulong r13; | ||
| 21 | ulong r14; | ||
| 22 | ulong r15; | ||
| 23 | ulong r16; | ||
| 24 | ulong r17; | ||
| 25 | ulong r18; | ||
| 26 | ulong r19; | ||
| 27 | ulong r20; | ||
| 28 | ulong r21; | ||
| 29 | ulong r22; | ||
| 30 | ulong r23; | ||
| 31 | ulong r24; | ||
| 32 | ulong r25; | ||
| 33 | ulong r26; | ||
| 34 | ulong r27; | ||
| 35 | ulong r28; | ||
| 36 | ulong r29; | ||
| 37 | ulong r30; | ||
| 38 | ulong r31; | ||
| 39 | ulong y; | ||
| 40 | ulong tbr; | ||
| 41 | ulong psr; | ||
| 42 | ulong npc; | ||
| 43 | ulong pc; | ||
| 44 | ulong pad; /* so structure is double word aligned */ | ||
| 45 | }; | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | #include <u.h> | ||
| 2 | #include <kern.h> | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Extensions for Inferno to basic libc.h | ||
| 6 | */ | ||
| 7 | |||
| 8 | #define __LITTLE_ENDIAN /* math/dtoa.c; longs in MIPS doubles are little-endian in LE mode */ | ||
| @@ -0,0 +1,56 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | typedef unsigned short ushort; | ||
| 3 | typedef unsigned char uchar; | ||
| 4 | typedef unsigned long ulong; | ||
| 5 | typedef unsigned int uint; | ||
| 6 | typedef signed char schar; | ||
| 7 | typedef long long vlong; | ||
| 8 | typedef unsigned long long uvlong; | ||
| 9 | typedef ushort Rune; | ||
| 10 | typedef union FPdbleword FPdbleword; | ||
| 11 | typedef long jmp_buf[2]; | ||
| 12 | #define JMPBUFSP 0 | ||
| 13 | #define JMPBUFPC 1 | ||
| 14 | #define JMPBUFDPC 0 | ||
| 15 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 16 | typedef unsigned int u32int; /* for /sys/include/libsec.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned long uintptr; | ||
| 20 | |||
| 21 | /* FCR */ | ||
| 22 | #define FPINEX (1<<7) | ||
| 23 | #define FPUNFL (1<<8) | ||
| 24 | #define FPOVFL (1<<9) | ||
| 25 | #define FPZDIV (1<<10) | ||
| 26 | #define FPINVAL (1<<11) | ||
| 27 | #define FPRNR (0<<0) | ||
| 28 | #define FPRZ (1<<0) | ||
| 29 | #define FPRPINF (2<<0) | ||
| 30 | #define FPRNINF (3<<0) | ||
| 31 | #define FPRMASK (3<<0) | ||
| 32 | #define FPPEXT 0 | ||
| 33 | #define FPPSGL 0 | ||
| 34 | #define FPPDBL 0 | ||
| 35 | #define FPPMASK 0 | ||
| 36 | /* FSR */ | ||
| 37 | #define FPAINEX (1<<2) | ||
| 38 | #define FPAOVFL (1<<4) | ||
| 39 | #define FPAUNFL (1<<3) | ||
| 40 | #define FPAZDIV (1<<5) | ||
| 41 | #define FPAINVAL (1<<6) | ||
| 42 | union FPdbleword | ||
| 43 | { | ||
| 44 | double x; | ||
| 45 | struct { /* little endian */ | ||
| 46 | ulong lo; | ||
| 47 | ulong hi; | ||
| 48 | }; | ||
| 49 | }; | ||
| 50 | |||
| 51 | /* stdarg */ | ||
| 52 | typedef char *va_list; | ||
| 53 | #define va_start(list, start) list = (sizeof(start)<4 ? (char *)((int *)&(start)+1) : \ | ||
| 54 | (char *)(&(start)+1)) | ||
| 55 | #define va_arg(list, mode) ((mode*)(list += sizeof(mode)))[-1] | ||
| 56 | #define va_end(list) | ||
| @@ -0,0 +1,8 @@ | |||
| 1 | #include <u.h> | ||
| 2 | #include <kern.h> | ||
| 3 | |||
| 4 | /* | ||
| 5 | * Extensions for Inferno to basic libc.h | ||
| 6 | */ | ||
| 7 | |||
| 8 | #undef __LITTLE_ENDIAN /* math/dtoa.c; longs in ARM doubles are big-endian */ | ||
| @@ -0,0 +1,65 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | |||
| 3 | typedef unsigned short ushort; | ||
| 4 | typedef unsigned char uchar; | ||
| 5 | typedef unsigned long ulong; | ||
| 6 | typedef unsigned int uint; | ||
| 7 | typedef signed char schar; | ||
| 8 | typedef long long vlong; | ||
| 9 | typedef unsigned long long uvlong; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC 0 | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | typedef unsigned long uintptr; | ||
| 22 | |||
| 23 | /* FCR */ | ||
| 24 | #define FPINEX (1<<20) | ||
| 25 | #define FPUNFL (1<<19) | ||
| 26 | #define FPOVFL (1<<18) | ||
| 27 | #define FPZDIV (1<<17) | ||
| 28 | #define FPINVAL (1<<16) | ||
| 29 | #define FPRNR (0<<0) | ||
| 30 | #define FPRZ (1<<0) | ||
| 31 | #define FPRPINF (2<<0) | ||
| 32 | #define FPRNINF (3<<0) | ||
| 33 | #define FPRMASK (3<<0) | ||
| 34 | #define FPPEXT 0 | ||
| 35 | #define FPPSGL 0 | ||
| 36 | #define FPPDBL 0 | ||
| 37 | #define FPPMASK 0 | ||
| 38 | /* FSR */ | ||
| 39 | #define FPAINEX (1<<4) | ||
| 40 | #define FPAUNFL (1<<3) | ||
| 41 | #define FPAOVFL (1<<2) | ||
| 42 | #define FPAZDIV (1<<1) | ||
| 43 | #define FPAINVAL (1<<0) | ||
| 44 | union FPdbleword | ||
| 45 | { | ||
| 46 | double x; | ||
| 47 | struct { /* big endian (on 7500) */ | ||
| 48 | ulong hi; | ||
| 49 | ulong lo; | ||
| 50 | }; | ||
| 51 | }; | ||
| 52 | |||
| 53 | typedef char* va_list; | ||
| 54 | #define va_start(list, start) list =\ | ||
| 55 | (sizeof(start) < 4?\ | ||
| 56 | (char*)((int*)&(start)+1):\ | ||
| 57 | (char*)(&(start)+1)) | ||
| 58 | #define va_end(list)\ | ||
| 59 | USED(list) | ||
| 60 | #define va_arg(list, mode)\ | ||
| 61 | ((sizeof(mode) == 1)?\ | ||
| 62 | ((mode*)(list += 4))[-4]:\ | ||
| 63 | (sizeof(mode) == 2)?\ | ||
| 64 | ((mode*)(list += 4))[-2]:\ | ||
| 65 | ((mode*)(list += sizeof(mode)))[-1]) | ||
| @@ -0,0 +1,24 @@ | |||
| 1 | typedef struct Ureg { | ||
| 2 | uint r0; | ||
| 3 | uint r1; | ||
| 4 | uint r2; | ||
| 5 | uint r3; | ||
| 6 | uint r4; | ||
| 7 | uint r5; | ||
| 8 | uint r6; | ||
| 9 | uint r7; | ||
| 10 | uint r8; | ||
| 11 | uint r9; | ||
| 12 | uint r10; | ||
| 13 | uint r11; | ||
| 14 | uint r12; | ||
| 15 | union { | ||
| 16 | uint r13; | ||
| 17 | uint sp; | ||
| 18 | }; | ||
| 19 | uint r14; | ||
| 20 | uint link; | ||
| 21 | uint type; | ||
| 22 | uint psr; | ||
| 23 | uint pc; | ||
| 24 | } Ureg; | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,22 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc** Xup; | ||
| 8 | #define up (*Xup) | ||
| 9 | |||
| 10 | typedef struct FPU FPU; | ||
| 11 | |||
| 12 | /* | ||
| 13 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 14 | */ | ||
| 15 | struct FPU | ||
| 16 | { | ||
| 17 | ulong fcr31; | ||
| 18 | }; | ||
| 19 | |||
| 20 | typedef sigjmp_buf osjmpbuf; | ||
| 21 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| 22 | |||
| @@ -0,0 +1,454 @@ | |||
| 1 | #define _LARGEFILE64_SOURCE 1 | ||
| 2 | #define _FILE_OFFSET_BITS 64 | ||
| 3 | #include <sys/types.h> | ||
| 4 | #include <sys/stat.h> | ||
| 5 | #define _POSIX_SOURCE | ||
| 6 | #include <stdlib.h> | ||
| 7 | #include <stdarg.h> | ||
| 8 | #include <unistd.h> | ||
| 9 | #include <errno.h> | ||
| 10 | #include <string.h> | ||
| 11 | #include "math.h" | ||
| 12 | #include <fcntl.h> | ||
| 13 | #include <setjmp.h> | ||
| 14 | #include <float.h> | ||
| 15 | #include <sys/bsd_types.h> | ||
| 16 | #include <time.h> | ||
| 17 | |||
| 18 | #define getwd infgetwd | ||
| 19 | |||
| 20 | #ifndef EMU | ||
| 21 | typedef struct Proc Proc; | ||
| 22 | #endif | ||
| 23 | |||
| 24 | #define nil ((void*)0) | ||
| 25 | |||
| 26 | typedef unsigned char uchar; | ||
| 27 | typedef signed char schar; | ||
| 28 | typedef unsigned short Rune; | ||
| 29 | typedef long long int vlong; | ||
| 30 | typedef unsigned long long int uvlong; | ||
| 31 | typedef unsigned int u32int; | ||
| 32 | typedef uvlong u64int; | ||
| 33 | |||
| 34 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 35 | typedef unsigned short u16int; | ||
| 36 | typedef unsigned char u8int; | ||
| 37 | typedef unsigned long uintptr; | ||
| 38 | |||
| 39 | typedef signed char int8; | ||
| 40 | typedef unsigned char uint8; | ||
| 41 | typedef short int16; | ||
| 42 | typedef unsigned short uint16; | ||
| 43 | typedef int int32; | ||
| 44 | typedef unsigned int uint32; | ||
| 45 | typedef long long int64; | ||
| 46 | typedef unsigned long long uint64; | ||
| 47 | |||
| 48 | #define USED(x) if(x){}else{} | ||
| 49 | #define SET(x) | ||
| 50 | |||
| 51 | #undef nelem | ||
| 52 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 53 | #undef offsetof | ||
| 54 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 55 | #undef assert | ||
| 56 | #define assert(x) if(x){}else _assert("x") | ||
| 57 | |||
| 58 | /* | ||
| 59 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 60 | */ | ||
| 61 | |||
| 62 | extern char* strecpy(char*, char*, char*); | ||
| 63 | extern char* strdup(const char*); | ||
| 64 | extern int cistrncmp(char*, char*, int); | ||
| 65 | extern int cistrcmp(char*, char*); | ||
| 66 | extern char* cistrstr(char*, char*); | ||
| 67 | extern int tokenize(char*, char**, int); | ||
| 68 | |||
| 69 | enum | ||
| 70 | { | ||
| 71 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 72 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 73 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 74 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 75 | }; | ||
| 76 | |||
| 77 | /* | ||
| 78 | * rune routines | ||
| 79 | */ | ||
| 80 | extern int runetochar(char*, Rune*); | ||
| 81 | extern int chartorune(Rune*, char*); | ||
| 82 | extern int runelen(long); | ||
| 83 | extern int runenlen(Rune*, int); | ||
| 84 | extern int fullrune(char*, int); | ||
| 85 | extern int utflen(char*); | ||
| 86 | extern int utfnlen(char*, long); | ||
| 87 | extern char* utfrune(char*, long); | ||
| 88 | extern char* utfrrune(char*, long); | ||
| 89 | extern char* utfutf(char*, char*); | ||
| 90 | extern char* utfecpy(char*, char*, char*); | ||
| 91 | |||
| 92 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 93 | extern Rune* runestrchr(Rune*, Rune); | ||
| 94 | extern int runestrcmp(Rune*, Rune*); | ||
| 95 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 96 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 97 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 98 | extern Rune* runestrdup(Rune*); | ||
| 99 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 100 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 101 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 102 | extern long runestrlen(Rune*); | ||
| 103 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 104 | |||
| 105 | extern Rune tolowerrune(Rune); | ||
| 106 | extern Rune totitlerune(Rune); | ||
| 107 | extern Rune toupperrune(Rune); | ||
| 108 | extern int isalpharune(Rune); | ||
| 109 | extern int islowerrune(Rune); | ||
| 110 | extern int isspacerune(Rune); | ||
| 111 | extern int istitlerune(Rune); | ||
| 112 | extern int isupperrune(Rune); | ||
| 113 | |||
| 114 | /* | ||
| 115 | * malloc | ||
| 116 | */ | ||
| 117 | extern void* malloc(size_t); | ||
| 118 | extern void* mallocz(ulong, int); | ||
| 119 | extern void free(void*); | ||
| 120 | extern ulong msize(void*); | ||
| 121 | extern void* calloc(size_t, size_t); | ||
| 122 | extern void* realloc(void*, size_t); | ||
| 123 | extern void setmalloctag(void*, ulong); | ||
| 124 | extern void setrealloctag(void*, ulong); | ||
| 125 | extern ulong getmalloctag(void*); | ||
| 126 | extern ulong getrealloctag(void*); | ||
| 127 | extern void* malloctopoolblock(void*); | ||
| 128 | |||
| 129 | /* | ||
| 130 | * print routines | ||
| 131 | */ | ||
| 132 | typedef struct Fmt Fmt; | ||
| 133 | struct Fmt{ | ||
| 134 | uchar runes; /* output buffer is runes or chars? */ | ||
| 135 | void *start; /* of buffer */ | ||
| 136 | void *to; /* current place in the buffer */ | ||
| 137 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 138 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 139 | void *farg; /* to make flush a closure */ | ||
| 140 | int nfmt; /* num chars formatted so far */ | ||
| 141 | va_list args; /* args passed to dofmt */ | ||
| 142 | int r; /* % format Rune */ | ||
| 143 | int width; | ||
| 144 | int prec; | ||
| 145 | ulong flags; | ||
| 146 | }; | ||
| 147 | extern vlong osnsec(void); | ||
| 148 | #define nsec osnsec | ||
| 149 | |||
| 150 | enum{ | ||
| 151 | FmtWidth = 1, | ||
| 152 | FmtLeft = FmtWidth << 1, | ||
| 153 | FmtPrec = FmtLeft << 1, | ||
| 154 | FmtSharp = FmtPrec << 1, | ||
| 155 | FmtSpace = FmtSharp << 1, | ||
| 156 | FmtSign = FmtSpace << 1, | ||
| 157 | FmtZero = FmtSign << 1, | ||
| 158 | FmtUnsigned = FmtZero << 1, | ||
| 159 | FmtShort = FmtUnsigned << 1, | ||
| 160 | FmtLong = FmtShort << 1, | ||
| 161 | FmtVLong = FmtLong << 1, | ||
| 162 | FmtComma = FmtVLong << 1, | ||
| 163 | FmtByte = FmtComma << 1, | ||
| 164 | |||
| 165 | FmtFlag = FmtByte << 1 | ||
| 166 | }; | ||
| 167 | |||
| 168 | extern int print(char*, ...); | ||
| 169 | extern char* seprint(char*, char*, char*, ...); | ||
| 170 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 171 | extern int snprint(char*, int, char*, ...); | ||
| 172 | extern int vsnprint(char*, int, char*, va_list); | ||
| 173 | extern char* smprint(char*, ...); | ||
| 174 | extern char* vsmprint(char*, va_list); | ||
| 175 | extern int sprint(char*, char*, ...); | ||
| 176 | extern int fprint(int, char*, ...); | ||
| 177 | extern int vfprint(int, char*, va_list); | ||
| 178 | |||
| 179 | extern int runesprint(Rune*, char*, ...); | ||
| 180 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 181 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 182 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 183 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 184 | extern Rune* runesmprint(char*, ...); | ||
| 185 | extern Rune* runevsmprint(char*, va_list); | ||
| 186 | |||
| 187 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 188 | extern int fmtfdflush(Fmt*); | ||
| 189 | extern int fmtstrinit(Fmt*); | ||
| 190 | extern char* fmtstrflush(Fmt*); | ||
| 191 | extern int runefmtstrinit(Fmt*); | ||
| 192 | extern Rune* runefmtstrflush(Fmt*); | ||
| 193 | |||
| 194 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 195 | extern int dofmt(Fmt*, char*); | ||
| 196 | extern int dorfmt(Fmt*, Rune*); | ||
| 197 | extern int fmtprint(Fmt*, char*, ...); | ||
| 198 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 199 | extern int fmtrune(Fmt*, int); | ||
| 200 | extern int fmtstrcpy(Fmt*, char*); | ||
| 201 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 202 | /* | ||
| 203 | * error string for %r | ||
| 204 | * supplied on per os basis, not part of fmt library | ||
| 205 | */ | ||
| 206 | extern int errfmt(Fmt *f); | ||
| 207 | |||
| 208 | /* | ||
| 209 | * quoted strings | ||
| 210 | */ | ||
| 211 | extern char *unquotestrdup(char*); | ||
| 212 | extern Rune *unquoterunestrdup(Rune*); | ||
| 213 | extern char *quotestrdup(char*); | ||
| 214 | extern Rune *quoterunestrdup(Rune*); | ||
| 215 | extern int quotestrfmt(Fmt*); | ||
| 216 | extern int quoterunestrfmt(Fmt*); | ||
| 217 | extern void quotefmtinstall(void); | ||
| 218 | extern int (*doquote)(int); | ||
| 219 | |||
| 220 | /* | ||
| 221 | * random number | ||
| 222 | */ | ||
| 223 | extern ulong truerand(void); | ||
| 224 | extern ulong ntruerand(ulong); | ||
| 225 | |||
| 226 | /* | ||
| 227 | * math | ||
| 228 | */ | ||
| 229 | extern int isNaN(double); | ||
| 230 | extern int isInf(double, int); | ||
| 231 | |||
| 232 | /* | ||
| 233 | * Time-of-day | ||
| 234 | */ | ||
| 235 | |||
| 236 | typedef struct Tm Tm; | ||
| 237 | struct Tm { | ||
| 238 | int sec; | ||
| 239 | int min; | ||
| 240 | int hour; | ||
| 241 | int mday; | ||
| 242 | int mon; | ||
| 243 | int year; | ||
| 244 | int wday; | ||
| 245 | int yday; | ||
| 246 | char zone[4]; | ||
| 247 | int tzoff; | ||
| 248 | }; | ||
| 249 | |||
| 250 | /* | ||
| 251 | * one-of-a-kind | ||
| 252 | */ | ||
| 253 | extern void _assert(char*); | ||
| 254 | extern double charstod(int(*)(void*), void*); | ||
| 255 | extern char* cleanname(char*); | ||
| 256 | extern uintptr getcallerpc(void*); | ||
| 257 | extern int getfields(char*, char**, int, int, char*); | ||
| 258 | extern char* getuser(void); | ||
| 259 | extern char* getwd(char*, int); | ||
| 260 | extern double ipow10(int); | ||
| 261 | #define pow10 infpow10 | ||
| 262 | extern double pow10(int); | ||
| 263 | extern vlong strtoll(const char*, char**, int); | ||
| 264 | #define qsort infqsort | ||
| 265 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 266 | extern uvlong strtoull(const char*, char**, int); | ||
| 267 | extern void sysfatal(char*, ...); | ||
| 268 | extern int dec64(uchar*, int, char*, int); | ||
| 269 | extern int enc64(char*, int, uchar*, int); | ||
| 270 | extern int dec32(uchar*, int, char*, int); | ||
| 271 | extern int enc32(char*, int, uchar*, int); | ||
| 272 | extern int dec16(uchar*, int, char*, int); | ||
| 273 | extern int enc16(char*, int, uchar*, int); | ||
| 274 | extern int encodefmt(Fmt*); | ||
| 275 | |||
| 276 | /* | ||
| 277 | * synchronization | ||
| 278 | */ | ||
| 279 | typedef | ||
| 280 | struct Lock { | ||
| 281 | int val; | ||
| 282 | int pid; | ||
| 283 | } Lock; | ||
| 284 | |||
| 285 | extern int _tas(int*); | ||
| 286 | |||
| 287 | extern void lock(Lock*); | ||
| 288 | extern void unlock(Lock*); | ||
| 289 | extern int canlock(Lock*); | ||
| 290 | |||
| 291 | typedef struct QLock QLock; | ||
| 292 | struct QLock | ||
| 293 | { | ||
| 294 | Lock use; /* to access Qlock structure */ | ||
| 295 | Proc *head; /* next process waiting for object */ | ||
| 296 | Proc *tail; /* last process waiting for object */ | ||
| 297 | int locked; /* flag */ | ||
| 298 | }; | ||
| 299 | |||
| 300 | extern void qlock(QLock*); | ||
| 301 | extern void qunlock(QLock*); | ||
| 302 | extern int canqlock(QLock*); | ||
| 303 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 304 | |||
| 305 | typedef | ||
| 306 | struct RWLock | ||
| 307 | { | ||
| 308 | Lock l; /* Lock modify lock */ | ||
| 309 | QLock x; /* Mutual exclusion lock */ | ||
| 310 | QLock k; /* Lock for waiting writers */ | ||
| 311 | int readers; /* Count of readers in lock */ | ||
| 312 | } RWLock; | ||
| 313 | |||
| 314 | extern int canrlock(RWLock*); | ||
| 315 | extern int canwlock(RWLock*); | ||
| 316 | extern void rlock(RWLock*); | ||
| 317 | extern void runlock(RWLock*); | ||
| 318 | extern void wlock(RWLock*); | ||
| 319 | extern void wunlock(RWLock*); | ||
| 320 | |||
| 321 | /* | ||
| 322 | * network dialing | ||
| 323 | */ | ||
| 324 | #define NETPATHLEN 40 | ||
| 325 | |||
| 326 | /* | ||
| 327 | * system calls | ||
| 328 | * | ||
| 329 | */ | ||
| 330 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 331 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 332 | #define ERRMAX 128 /* max length of error string */ | ||
| 333 | |||
| 334 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 335 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 336 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 337 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 338 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 339 | #define MCACHE 0x0010 /* cache some data */ | ||
| 340 | #define MMASK 0x0017 /* all bits on */ | ||
| 341 | |||
| 342 | #define OREAD 0 /* open for read */ | ||
| 343 | #define OWRITE 1 /* write */ | ||
| 344 | #define ORDWR 2 /* read and write */ | ||
| 345 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 346 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 347 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 348 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 349 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 350 | |||
| 351 | #define AEXIST 0 /* accessible: exists */ | ||
| 352 | #define AEXEC 1 /* execute access */ | ||
| 353 | #define AWRITE 2 /* write access */ | ||
| 354 | #define AREAD 4 /* read access */ | ||
| 355 | |||
| 356 | /* bits in Qid.type */ | ||
| 357 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 358 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 359 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 360 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 361 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 362 | #define QTFILE 0x00 /* plain file */ | ||
| 363 | |||
| 364 | /* bits in Dir.mode */ | ||
| 365 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 366 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 367 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 368 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 369 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 370 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 371 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 372 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 373 | |||
| 374 | typedef | ||
| 375 | struct Qid | ||
| 376 | { | ||
| 377 | uvlong path; | ||
| 378 | ulong vers; | ||
| 379 | uchar type; | ||
| 380 | } Qid; | ||
| 381 | |||
| 382 | typedef | ||
| 383 | struct Dir { | ||
| 384 | /* system-modified data */ | ||
| 385 | ushort type; /* server type */ | ||
| 386 | uint dev; /* server subtype */ | ||
| 387 | /* file data */ | ||
| 388 | Qid qid; /* unique id from server */ | ||
| 389 | ulong mode; /* permissions */ | ||
| 390 | ulong atime; /* last read time */ | ||
| 391 | ulong mtime; /* last write time */ | ||
| 392 | vlong length; /* file length */ | ||
| 393 | char *name; /* last element of path */ | ||
| 394 | char *uid; /* owner name */ | ||
| 395 | char *gid; /* group name */ | ||
| 396 | char *muid; /* last modifier name */ | ||
| 397 | } Dir; | ||
| 398 | |||
| 399 | extern Dir* dirstat(char*); | ||
| 400 | extern Dir* dirfstat(int); | ||
| 401 | extern int dirwstat(char*, Dir*); | ||
| 402 | extern int dirfwstat(int, Dir*); | ||
| 403 | extern long dirread(int, Dir**); | ||
| 404 | extern void nulldir(Dir*); | ||
| 405 | extern long dirreadall(int, Dir**); | ||
| 406 | |||
| 407 | typedef | ||
| 408 | struct Waitmsg | ||
| 409 | { | ||
| 410 | int pid; /* of loved one */ | ||
| 411 | ulong time[3]; /* of loved one & descendants */ | ||
| 412 | char *msg; | ||
| 413 | } Waitmsg; | ||
| 414 | |||
| 415 | extern void _exits(char*); | ||
| 416 | |||
| 417 | extern void exits(char*); | ||
| 418 | extern int create(char*, int, int); | ||
| 419 | extern int errstr(char*, uint); | ||
| 420 | |||
| 421 | extern void perror(const char*); | ||
| 422 | extern long readn(int, void*, long); | ||
| 423 | extern int remove(const char*); | ||
| 424 | extern void rerrstr(char*, uint); | ||
| 425 | extern vlong seek(int, vlong, int); | ||
| 426 | extern void werrstr(char*, ...); | ||
| 427 | |||
| 428 | extern char *argv0; | ||
| 429 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 430 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 431 | argc--, argv++) {\ | ||
| 432 | char *_args, *_argt;\ | ||
| 433 | Rune _argc;\ | ||
| 434 | _args = &argv[0][1];\ | ||
| 435 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 436 | argc--; argv++; break;\ | ||
| 437 | }\ | ||
| 438 | _argc = 0;\ | ||
| 439 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 440 | switch(_argc) | ||
| 441 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 442 | #define ARGF() (_argt=_args, _args="",\ | ||
| 443 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 444 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 445 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 446 | |||
| 447 | #define ARGC() _argc | ||
| 448 | |||
| 449 | /* | ||
| 450 | * Extensions for Inferno to basic libc.h | ||
| 451 | */ | ||
| 452 | |||
| 453 | #define setbinmode() | ||
| 454 | |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,33 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 9 | */ | ||
| 10 | typedef struct FPU FPU; | ||
| 11 | struct FPU | ||
| 12 | { | ||
| 13 | uchar env[28]; | ||
| 14 | }; | ||
| 15 | |||
| 16 | #define KSTACK (32 * 1024) | ||
| 17 | |||
| 18 | #ifndef USE_PTHREADS | ||
| 19 | static __inline Proc *getup(void) { | ||
| 20 | Proc *p; | ||
| 21 | __asm__( "movl %%esp, %%eax\n\t" | ||
| 22 | : "=a" (p) | ||
| 23 | ); | ||
| 24 | return *(Proc **)((uintptr)p & ~(KSTACK - 1)); | ||
| 25 | } | ||
| 26 | #else | ||
| 27 | extern Proc* getup(void); | ||
| 28 | #endif | ||
| 29 | |||
| 30 | #define up (getup()) | ||
| 31 | |||
| 32 | typedef sigjmp_buf osjmpbuf; | ||
| 33 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Linux 386 fpu support | ||
| 3 | * Mimic Plan9 floating point support | ||
| 4 | */ | ||
| 5 | |||
| 6 | static void | ||
| 7 | setfcr(ulong fcr) | ||
| 8 | { | ||
| 9 | __asm__( "xorb $0x3f, %%al\n\t" | ||
| 10 | "pushw %%ax\n\t" | ||
| 11 | "fwait\n\t" | ||
| 12 | "fldcw (%%esp)\n\t" | ||
| 13 | "popw %%ax\n\t" | ||
| 14 | : /* no output */ | ||
| 15 | : "al" (fcr) | ||
| 16 | ); | ||
| 17 | } | ||
| 18 | |||
| 19 | static ulong | ||
| 20 | getfcr(void) | ||
| 21 | { | ||
| 22 | ulong fcr = 0; | ||
| 23 | |||
| 24 | __asm__( "pushl %%eax\n\t" | ||
| 25 | "fwait\n\t" | ||
| 26 | "fstcw (%%esp)\n\t" | ||
| 27 | "popl %%eax\n\t" | ||
| 28 | "xorb $0x3f, %%al\n\t" | ||
| 29 | : "=a" (fcr) | ||
| 30 | : "eax" (fcr) | ||
| 31 | ); | ||
| 32 | return fcr; | ||
| 33 | } | ||
| 34 | |||
| 35 | static ulong | ||
| 36 | getfsr(void) | ||
| 37 | { | ||
| 38 | ulong fsr = -1; | ||
| 39 | |||
| 40 | __asm__( "fwait\n\t" | ||
| 41 | "fstsw (%%eax)\n\t" | ||
| 42 | "movl (%%eax), %%eax\n\t" | ||
| 43 | "andl $0xffff, %%eax\n\t" | ||
| 44 | : "=a" (fsr) | ||
| 45 | : "eax" (&fsr) | ||
| 46 | ); | ||
| 47 | return fsr; | ||
| 48 | } | ||
| 49 | |||
| 50 | static void | ||
| 51 | setfsr(ulong fsr) | ||
| 52 | { | ||
| 53 | __asm__("fclex\n\t"); | ||
| 54 | } | ||
| 55 | |||
| 56 | /* FCR */ | ||
| 57 | #define FPINEX (1<<5) | ||
| 58 | #define FPUNFL ((1<<4)|(1<<1)) | ||
| 59 | #define FPOVFL (1<<3) | ||
| 60 | #define FPZDIV (1<<2) | ||
| 61 | #define FPINVAL (1<<0) | ||
| 62 | #define FPRNR (0<<10) | ||
| 63 | #define FPRZ (3<<10) | ||
| 64 | #define FPRPINF (2<<10) | ||
| 65 | #define FPRNINF (1<<10) | ||
| 66 | #define FPRMASK (3<<10) | ||
| 67 | #define FPPEXT (3<<8) | ||
| 68 | #define FPPSGL (0<<8) | ||
| 69 | #define FPPDBL (2<<8) | ||
| 70 | #define FPPMASK (3<<8) | ||
| 71 | /* FSR */ | ||
| 72 | #define FPAINEX FPINEX | ||
| 73 | #define FPAOVFL FPOVFL | ||
| 74 | #define FPAUNFL FPUNFL | ||
| 75 | #define FPAZDIV FPZDIV | ||
| 76 | #define FPAINVAL FPINVAL | ||
| @@ -0,0 +1,462 @@ | |||
| 1 | /* define _BSD_SOURCE to use ISO C, POSIX, and 4.3BSD things. */ | ||
| 2 | #define USE_PTHREADS | ||
| 3 | #ifndef _BSD_SOURCE | ||
| 4 | #define _BSD_SOURCE | ||
| 5 | #endif | ||
| 6 | #define _XOPEN_SOURCE 500 | ||
| 7 | #define _LARGEFILE_SOURCE 1 | ||
| 8 | #define _LARGEFILE64_SOURCE 1 | ||
| 9 | #define _FILE_OFFSET_BITS 64 | ||
| 10 | #ifdef USE_PTHREADS | ||
| 11 | #define _REENTRANT 1 | ||
| 12 | #endif | ||
| 13 | #include <features.h> | ||
| 14 | #include <sys/types.h> | ||
| 15 | #include <stdlib.h> | ||
| 16 | #include <stdarg.h> | ||
| 17 | #define sync __os_sync | ||
| 18 | #include <unistd.h> | ||
| 19 | #undef sync | ||
| 20 | #include <errno.h> | ||
| 21 | #define __NO_STRING_INLINES | ||
| 22 | #include <string.h> | ||
| 23 | #include "math.h" | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <setjmp.h> | ||
| 26 | #include <float.h> | ||
| 27 | #include <endian.h> | ||
| 28 | |||
| 29 | #define getwd infgetwd | ||
| 30 | |||
| 31 | #ifndef EMU | ||
| 32 | typedef struct Proc Proc; | ||
| 33 | #endif | ||
| 34 | |||
| 35 | /* | ||
| 36 | * math module dtoa | ||
| 37 | * #define __LITTLE_ENDIAN /usr/include/endian.h under linux | ||
| 38 | */ | ||
| 39 | |||
| 40 | #define nil ((void*)0) | ||
| 41 | |||
| 42 | typedef unsigned char uchar; | ||
| 43 | typedef signed char schar; | ||
| 44 | typedef unsigned short Rune; | ||
| 45 | typedef long long int vlong; | ||
| 46 | typedef unsigned long long int uvlong; | ||
| 47 | typedef unsigned int u32int; | ||
| 48 | typedef uvlong u64int; | ||
| 49 | |||
| 50 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 51 | typedef unsigned short u16int; | ||
| 52 | typedef unsigned char u8int; | ||
| 53 | typedef unsigned long uintptr; | ||
| 54 | |||
| 55 | #define USED(x) if(x){}else{} | ||
| 56 | #define SET(x) | ||
| 57 | |||
| 58 | #undef nelem | ||
| 59 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 60 | #undef offsetof | ||
| 61 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 62 | #undef assert | ||
| 63 | #define assert(x) if(x){}else _assert("x") | ||
| 64 | |||
| 65 | /* | ||
| 66 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 67 | */ | ||
| 68 | |||
| 69 | extern char* strecpy(char*, char*, char*); | ||
| 70 | extern char* strdup(const char*); | ||
| 71 | extern int cistrncmp(char*, char*, int); | ||
| 72 | extern int cistrcmp(char*, char*); | ||
| 73 | extern char* cistrstr(char*, char*); | ||
| 74 | extern int tokenize(char*, char**, int); | ||
| 75 | |||
| 76 | enum | ||
| 77 | { | ||
| 78 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 79 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 80 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 81 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 82 | }; | ||
| 83 | |||
| 84 | /* | ||
| 85 | * rune routines | ||
| 86 | */ | ||
| 87 | extern int runetochar(char*, Rune*); | ||
| 88 | extern int chartorune(Rune*, char*); | ||
| 89 | extern int runelen(long); | ||
| 90 | extern int runenlen(Rune*, int); | ||
| 91 | extern int fullrune(char*, int); | ||
| 92 | extern int utflen(char*); | ||
| 93 | extern int utfnlen(char*, long); | ||
| 94 | extern char* utfrune(char*, long); | ||
| 95 | extern char* utfrrune(char*, long); | ||
| 96 | extern char* utfutf(char*, char*); | ||
| 97 | extern char* utfecpy(char*, char*, char*); | ||
| 98 | |||
| 99 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 100 | extern Rune* runestrchr(Rune*, Rune); | ||
| 101 | extern int runestrcmp(Rune*, Rune*); | ||
| 102 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 103 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 104 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 105 | extern Rune* runestrdup(Rune*); | ||
| 106 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 107 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 108 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 109 | extern long runestrlen(Rune*); | ||
| 110 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 111 | |||
| 112 | extern Rune tolowerrune(Rune); | ||
| 113 | extern Rune totitlerune(Rune); | ||
| 114 | extern Rune toupperrune(Rune); | ||
| 115 | extern int isalpharune(Rune); | ||
| 116 | extern int islowerrune(Rune); | ||
| 117 | extern int isspacerune(Rune); | ||
| 118 | extern int istitlerune(Rune); | ||
| 119 | extern int isupperrune(Rune); | ||
| 120 | |||
| 121 | /* | ||
| 122 | * malloc | ||
| 123 | */ | ||
| 124 | extern void* malloc(size_t); | ||
| 125 | extern void* mallocz(ulong, int); | ||
| 126 | extern void free(void*); | ||
| 127 | extern ulong msize(void*); | ||
| 128 | extern void* calloc(size_t, size_t); | ||
| 129 | extern void* realloc(void*, size_t); | ||
| 130 | extern void setmalloctag(void*, ulong); | ||
| 131 | extern void setrealloctag(void*, ulong); | ||
| 132 | extern ulong getmalloctag(void*); | ||
| 133 | extern ulong getrealloctag(void*); | ||
| 134 | extern void* malloctopoolblock(void*); | ||
| 135 | |||
| 136 | /* | ||
| 137 | * print routines | ||
| 138 | */ | ||
| 139 | typedef struct Fmt Fmt; | ||
| 140 | struct Fmt{ | ||
| 141 | uchar runes; /* output buffer is runes or chars? */ | ||
| 142 | void *start; /* of buffer */ | ||
| 143 | void *to; /* current place in the buffer */ | ||
| 144 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 145 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 146 | void *farg; /* to make flush a closure */ | ||
| 147 | int nfmt; /* num chars formatted so far */ | ||
| 148 | va_list args; /* args passed to dofmt */ | ||
| 149 | int r; /* % format Rune */ | ||
| 150 | int width; | ||
| 151 | int prec; | ||
| 152 | ulong flags; | ||
| 153 | }; | ||
| 154 | |||
| 155 | enum{ | ||
| 156 | FmtWidth = 1, | ||
| 157 | FmtLeft = FmtWidth << 1, | ||
| 158 | FmtPrec = FmtLeft << 1, | ||
| 159 | FmtSharp = FmtPrec << 1, | ||
| 160 | FmtSpace = FmtSharp << 1, | ||
| 161 | FmtSign = FmtSpace << 1, | ||
| 162 | FmtZero = FmtSign << 1, | ||
| 163 | FmtUnsigned = FmtZero << 1, | ||
| 164 | FmtShort = FmtUnsigned << 1, | ||
| 165 | FmtLong = FmtShort << 1, | ||
| 166 | FmtVLong = FmtLong << 1, | ||
| 167 | FmtComma = FmtVLong << 1, | ||
| 168 | FmtByte = FmtComma << 1, | ||
| 169 | |||
| 170 | FmtFlag = FmtByte << 1 | ||
| 171 | }; | ||
| 172 | |||
| 173 | extern int print(char*, ...); | ||
| 174 | extern char* seprint(char*, char*, char*, ...); | ||
| 175 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 176 | extern int snprint(char*, int, char*, ...); | ||
| 177 | extern int vsnprint(char*, int, char*, va_list); | ||
| 178 | extern char* smprint(char*, ...); | ||
| 179 | extern char* vsmprint(char*, va_list); | ||
| 180 | extern int sprint(char*, char*, ...); | ||
| 181 | extern int fprint(int, char*, ...); | ||
| 182 | extern int vfprint(int, char*, va_list); | ||
| 183 | |||
| 184 | extern int runesprint(Rune*, char*, ...); | ||
| 185 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 186 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 187 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 188 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 189 | extern Rune* runesmprint(char*, ...); | ||
| 190 | extern Rune* runevsmprint(char*, va_list); | ||
| 191 | |||
| 192 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 193 | extern int fmtfdflush(Fmt*); | ||
| 194 | extern int fmtstrinit(Fmt*); | ||
| 195 | extern char* fmtstrflush(Fmt*); | ||
| 196 | extern int runefmtstrinit(Fmt*); | ||
| 197 | extern Rune* runefmtstrflush(Fmt*); | ||
| 198 | |||
| 199 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 200 | extern int dofmt(Fmt*, char*); | ||
| 201 | extern int dorfmt(Fmt*, Rune*); | ||
| 202 | extern int fmtprint(Fmt*, char*, ...); | ||
| 203 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 204 | extern int fmtrune(Fmt*, int); | ||
| 205 | extern int fmtstrcpy(Fmt*, char*); | ||
| 206 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 207 | /* | ||
| 208 | * error string for %r | ||
| 209 | * supplied on per os basis, not part of fmt library | ||
| 210 | */ | ||
| 211 | extern int errfmt(Fmt *f); | ||
| 212 | |||
| 213 | /* | ||
| 214 | * quoted strings | ||
| 215 | */ | ||
| 216 | extern char *unquotestrdup(char*); | ||
| 217 | extern Rune *unquoterunestrdup(Rune*); | ||
| 218 | extern char *quotestrdup(char*); | ||
| 219 | extern Rune *quoterunestrdup(Rune*); | ||
| 220 | extern int quotestrfmt(Fmt*); | ||
| 221 | extern int quoterunestrfmt(Fmt*); | ||
| 222 | extern void quotefmtinstall(void); | ||
| 223 | extern int (*doquote)(int); | ||
| 224 | |||
| 225 | /* | ||
| 226 | * random number | ||
| 227 | */ | ||
| 228 | extern ulong truerand(void); | ||
| 229 | extern ulong ntruerand(ulong); | ||
| 230 | |||
| 231 | /* | ||
| 232 | * math | ||
| 233 | */ | ||
| 234 | extern int isNaN(double); | ||
| 235 | extern int isInf(double, int); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * Time-of-day | ||
| 239 | */ | ||
| 240 | |||
| 241 | typedef struct Tm Tm; | ||
| 242 | struct Tm { | ||
| 243 | int sec; | ||
| 244 | int min; | ||
| 245 | int hour; | ||
| 246 | int mday; | ||
| 247 | int mon; | ||
| 248 | int year; | ||
| 249 | int wday; | ||
| 250 | int yday; | ||
| 251 | char zone[4]; | ||
| 252 | int tzoff; | ||
| 253 | }; | ||
| 254 | extern vlong osnsec(void); | ||
| 255 | #define nsec osnsec | ||
| 256 | |||
| 257 | /* | ||
| 258 | * one-of-a-kind | ||
| 259 | */ | ||
| 260 | extern void _assert(char*); | ||
| 261 | extern double charstod(int(*)(void*), void*); | ||
| 262 | extern char* cleanname(char*); | ||
| 263 | extern uintptr getcallerpc(void*); | ||
| 264 | extern int getfields(char*, char**, int, int, char*); | ||
| 265 | extern char* getuser(void); | ||
| 266 | extern char* getwd(char*, int); | ||
| 267 | extern double ipow10(int); | ||
| 268 | #define pow10 infpow10 | ||
| 269 | extern double pow10(int); | ||
| 270 | extern vlong strtoll(const char*, char**, int); | ||
| 271 | #define qsort infqsort | ||
| 272 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 273 | extern uvlong strtoull(const char*, char**, int); | ||
| 274 | extern void sysfatal(char*, ...); | ||
| 275 | extern int dec64(uchar*, int, char*, int); | ||
| 276 | extern int enc64(char*, int, uchar*, int); | ||
| 277 | extern int dec32(uchar*, int, char*, int); | ||
| 278 | extern int enc32(char*, int, uchar*, int); | ||
| 279 | extern int dec16(uchar*, int, char*, int); | ||
| 280 | extern int enc16(char*, int, uchar*, int); | ||
| 281 | extern int encodefmt(Fmt*); | ||
| 282 | |||
| 283 | /* | ||
| 284 | * synchronization | ||
| 285 | */ | ||
| 286 | typedef | ||
| 287 | struct Lock { | ||
| 288 | int val; | ||
| 289 | int pid; | ||
| 290 | } Lock; | ||
| 291 | |||
| 292 | extern int _tas(int*); | ||
| 293 | |||
| 294 | extern void lock(Lock*); | ||
| 295 | extern void unlock(Lock*); | ||
| 296 | extern int canlock(Lock*); | ||
| 297 | |||
| 298 | typedef struct QLock QLock; | ||
| 299 | struct QLock | ||
| 300 | { | ||
| 301 | Lock use; /* to access Qlock structure */ | ||
| 302 | Proc *head; /* next process waiting for object */ | ||
| 303 | Proc *tail; /* last process waiting for object */ | ||
| 304 | int locked; /* flag */ | ||
| 305 | }; | ||
| 306 | |||
| 307 | extern void qlock(QLock*); | ||
| 308 | extern void qunlock(QLock*); | ||
| 309 | extern int canqlock(QLock*); | ||
| 310 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 311 | |||
| 312 | typedef | ||
| 313 | struct RWLock | ||
| 314 | { | ||
| 315 | Lock l; /* Lock modify lock */ | ||
| 316 | QLock x; /* Mutual exclusion lock */ | ||
| 317 | QLock k; /* Lock for waiting writers */ | ||
| 318 | int readers; /* Count of readers in lock */ | ||
| 319 | } RWLock; | ||
| 320 | |||
| 321 | extern int canrlock(RWLock*); | ||
| 322 | extern int canwlock(RWLock*); | ||
| 323 | extern void rlock(RWLock*); | ||
| 324 | extern void runlock(RWLock*); | ||
| 325 | extern void wlock(RWLock*); | ||
| 326 | extern void wunlock(RWLock*); | ||
| 327 | |||
| 328 | /* | ||
| 329 | * network dialing | ||
| 330 | */ | ||
| 331 | #define NETPATHLEN 40 | ||
| 332 | |||
| 333 | /* | ||
| 334 | * system calls | ||
| 335 | * | ||
| 336 | */ | ||
| 337 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 338 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 339 | #define ERRMAX 128 /* max length of error string */ | ||
| 340 | |||
| 341 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 342 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 343 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 344 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 345 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 346 | #define MCACHE 0x0010 /* cache some data */ | ||
| 347 | #define MMASK 0x0017 /* all bits on */ | ||
| 348 | |||
| 349 | #define OREAD 0 /* open for read */ | ||
| 350 | #define OWRITE 1 /* write */ | ||
| 351 | #define ORDWR 2 /* read and write */ | ||
| 352 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 353 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 354 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 355 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 356 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 357 | |||
| 358 | #define AEXIST 0 /* accessible: exists */ | ||
| 359 | #define AEXEC 1 /* execute access */ | ||
| 360 | #define AWRITE 2 /* write access */ | ||
| 361 | #define AREAD 4 /* read access */ | ||
| 362 | |||
| 363 | /* bits in Qid.type */ | ||
| 364 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 365 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 366 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 367 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 368 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 369 | #define QTFILE 0x00 /* plain file */ | ||
| 370 | |||
| 371 | /* bits in Dir.mode */ | ||
| 372 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 373 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 374 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 375 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 376 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 377 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 378 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 379 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 380 | |||
| 381 | typedef | ||
| 382 | struct Qid | ||
| 383 | { | ||
| 384 | uvlong path; | ||
| 385 | ulong vers; | ||
| 386 | uchar type; | ||
| 387 | } Qid; | ||
| 388 | |||
| 389 | typedef | ||
| 390 | struct Dir { | ||
| 391 | /* system-modified data */ | ||
| 392 | ushort type; /* server type */ | ||
| 393 | uint dev; /* server subtype */ | ||
| 394 | /* file data */ | ||
| 395 | Qid qid; /* unique id from server */ | ||
| 396 | ulong mode; /* permissions */ | ||
| 397 | ulong atime; /* last read time */ | ||
| 398 | ulong mtime; /* last write time */ | ||
| 399 | vlong length; /* file length */ | ||
| 400 | char *name; /* last element of path */ | ||
| 401 | char *uid; /* owner name */ | ||
| 402 | char *gid; /* group name */ | ||
| 403 | char *muid; /* last modifier name */ | ||
| 404 | } Dir; | ||
| 405 | |||
| 406 | extern Dir* dirstat(char*); | ||
| 407 | extern Dir* dirfstat(int); | ||
| 408 | extern int dirwstat(char*, Dir*); | ||
| 409 | extern int dirfwstat(int, Dir*); | ||
| 410 | extern long dirread(int, Dir**); | ||
| 411 | extern void nulldir(Dir*); | ||
| 412 | extern long dirreadall(int, Dir**); | ||
| 413 | |||
| 414 | typedef | ||
| 415 | struct Waitmsg | ||
| 416 | { | ||
| 417 | int pid; /* of loved one */ | ||
| 418 | ulong time[3]; /* of loved one & descendants */ | ||
| 419 | char *msg; | ||
| 420 | } Waitmsg; | ||
| 421 | |||
| 422 | extern void _exits(char*); | ||
| 423 | |||
| 424 | extern void exits(char*); | ||
| 425 | extern int create(char*, int, int); | ||
| 426 | extern int errstr(char*, uint); | ||
| 427 | |||
| 428 | extern void perror(const char*); | ||
| 429 | extern long readn(int, void*, long); | ||
| 430 | extern int remove(const char*); | ||
| 431 | extern void rerrstr(char*, uint); | ||
| 432 | extern vlong seek(int, vlong, int); | ||
| 433 | extern int segflush(void*, ulong); | ||
| 434 | extern void werrstr(char*, ...); | ||
| 435 | |||
| 436 | extern char *argv0; | ||
| 437 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 438 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 439 | argc--, argv++) {\ | ||
| 440 | char *_args, *_argt;\ | ||
| 441 | Rune _argc;\ | ||
| 442 | _args = &argv[0][1];\ | ||
| 443 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 444 | argc--; argv++; break;\ | ||
| 445 | }\ | ||
| 446 | _argc = 0;\ | ||
| 447 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 448 | switch(_argc) | ||
| 449 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 450 | #define ARGF() (_argt=_args, _args="",\ | ||
| 451 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 452 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 453 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 454 | |||
| 455 | #define ARGC() _argc | ||
| 456 | |||
| 457 | /* | ||
| 458 | * Extensions for Inferno to basic libc.h | ||
| 459 | */ | ||
| 460 | |||
| 461 | #define setbinmode() | ||
| 462 | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 9 | */ | ||
| 10 | typedef struct FPU FPU; | ||
| 11 | struct FPU | ||
| 12 | { | ||
| 13 | uchar env[28]; | ||
| 14 | }; | ||
| 15 | |||
| 16 | |||
| 17 | #ifndef USE_PTHREADS | ||
| 18 | #define KSTACK (16 * 1024) /* must be power of two */ | ||
| 19 | static __inline Proc *getup(void) { | ||
| 20 | Proc *p; | ||
| 21 | __asm__( "mov %0, %%sp;" | ||
| 22 | : "=r" (p) | ||
| 23 | ); | ||
| 24 | return *(Proc **)((uintptr)p & ~(KSTACK - 1)); | ||
| 25 | } | ||
| 26 | #else | ||
| 27 | #define KSTACK (32 * 1024) /* need not be power of two */ | ||
| 28 | extern Proc* getup(void); | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #define up (getup()) | ||
| 32 | |||
| 33 | typedef sigjmp_buf osjmpbuf; | ||
| 34 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| @@ -0,0 +1,52 @@ | |||
| 1 | /* | ||
| 2 | * Linux arm fpu support | ||
| 3 | * Mimic Plan9 floating point support | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <fenv.h> | ||
| 7 | |||
| 8 | static void | ||
| 9 | setfcr(ulong fcr) | ||
| 10 | { | ||
| 11 | } | ||
| 12 | |||
| 13 | static ulong | ||
| 14 | getfcr(void) | ||
| 15 | { | ||
| 16 | ulong fcr = 0; | ||
| 17 | return fcr; | ||
| 18 | } | ||
| 19 | |||
| 20 | static ulong | ||
| 21 | getfsr(void) | ||
| 22 | { | ||
| 23 | ulong fsr = -1; | ||
| 24 | return fsr; | ||
| 25 | } | ||
| 26 | |||
| 27 | static void | ||
| 28 | setfsr(ulong fsr) | ||
| 29 | { | ||
| 30 | } | ||
| 31 | |||
| 32 | /* FCR */ | ||
| 33 | #define FPINEX (1<<5) | ||
| 34 | #define FPUNFL ((1<<4)|(1<<1)) | ||
| 35 | #define FPOVFL (1<<3) | ||
| 36 | #define FPZDIV (1<<2) | ||
| 37 | #define FPINVAL (1<<0) | ||
| 38 | #define FPRNR (0<<10) | ||
| 39 | #define FPRZ (3<<10) | ||
| 40 | #define FPRPINF (2<<10) | ||
| 41 | #define FPRNINF (1<<10) | ||
| 42 | #define FPRMASK (3<<10) | ||
| 43 | #define FPPEXT (3<<8) | ||
| 44 | #define FPPSGL (0<<8) | ||
| 45 | #define FPPDBL (2<<8) | ||
| 46 | #define FPPMASK (3<<8) | ||
| 47 | /* FSR */ | ||
| 48 | #define FPAINEX FPINEX | ||
| 49 | #define FPAOVFL FPOVFL | ||
| 50 | #define FPAUNFL FPUNFL | ||
| 51 | #define FPAZDIV FPZDIV | ||
| 52 | #define FPAINVAL FPINVAL | ||
| @@ -0,0 +1,470 @@ | |||
| 1 | /* define _BSD_SOURCE to use ISO C, POSIX, and 4.3BSD things. */ | ||
| 2 | #define USE_PTHREADS | ||
| 3 | #ifndef _BSD_SOURCE | ||
| 4 | #define _BSD_SOURCE | ||
| 5 | #endif | ||
| 6 | #define _XOPEN_SOURCE 500 | ||
| 7 | #define _LARGEFILE_SOURCE 1 | ||
| 8 | #define _LARGEFILE64_SOURCE 1 | ||
| 9 | #define _FILE_OFFSET_BITS 64 | ||
| 10 | #ifdef USE_PTHREADS | ||
| 11 | #define _REENTRANT 1 | ||
| 12 | #endif | ||
| 13 | #include <features.h> | ||
| 14 | #include <sys/types.h> | ||
| 15 | #include <stdlib.h> | ||
| 16 | #include <stdarg.h> | ||
| 17 | #define sync __os_sync | ||
| 18 | #include <unistd.h> | ||
| 19 | #undef sync | ||
| 20 | #include <errno.h> | ||
| 21 | #define __NO_STRING_INLINES | ||
| 22 | #include <string.h> | ||
| 23 | #include "math.h" | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <setjmp.h> | ||
| 26 | #include <float.h> | ||
| 27 | #include <endian.h> | ||
| 28 | |||
| 29 | #define getwd infgetwd | ||
| 30 | |||
| 31 | #ifndef EMU | ||
| 32 | typedef struct Proc Proc; | ||
| 33 | #endif | ||
| 34 | |||
| 35 | /* | ||
| 36 | * math module dtoa | ||
| 37 | * #define __LITTLE_ENDIAN /usr/include/endian.h under linux | ||
| 38 | */ | ||
| 39 | |||
| 40 | #define nil ((void*)0) | ||
| 41 | |||
| 42 | typedef unsigned char uchar; | ||
| 43 | typedef signed char schar; | ||
| 44 | typedef unsigned short Rune; | ||
| 45 | typedef long long int vlong; | ||
| 46 | typedef unsigned long long int uvlong; | ||
| 47 | typedef unsigned int u32int; | ||
| 48 | typedef uvlong u64int; | ||
| 49 | |||
| 50 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 51 | typedef unsigned short u16int; | ||
| 52 | typedef unsigned char u8int; | ||
| 53 | typedef unsigned long uintptr; | ||
| 54 | |||
| 55 | #define USED(x) if(x){}else{} | ||
| 56 | #define SET(x) | ||
| 57 | |||
| 58 | #undef nelem | ||
| 59 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 60 | #undef offsetof | ||
| 61 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 62 | #undef assert | ||
| 63 | #define assert(x) if(x){}else _assert("x") | ||
| 64 | |||
| 65 | /* | ||
| 66 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 67 | */ | ||
| 68 | |||
| 69 | extern char* strecpy(char*, char*, char*); | ||
| 70 | extern char* strdup(const char*); | ||
| 71 | extern int cistrncmp(char*, char*, int); | ||
| 72 | extern int cistrcmp(char*, char*); | ||
| 73 | extern char* cistrstr(char*, char*); | ||
| 74 | extern int tokenize(char*, char**, int); | ||
| 75 | |||
| 76 | enum | ||
| 77 | { | ||
| 78 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 79 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 80 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 81 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 82 | }; | ||
| 83 | |||
| 84 | /* | ||
| 85 | * rune routines | ||
| 86 | */ | ||
| 87 | extern int runetochar(char*, Rune*); | ||
| 88 | extern int chartorune(Rune*, char*); | ||
| 89 | extern int runelen(long); | ||
| 90 | extern int runenlen(Rune*, int); | ||
| 91 | extern int fullrune(char*, int); | ||
| 92 | extern int utflen(char*); | ||
| 93 | extern int utfnlen(char*, long); | ||
| 94 | extern char* utfrune(char*, long); | ||
| 95 | extern char* utfrrune(char*, long); | ||
| 96 | extern char* utfutf(char*, char*); | ||
| 97 | extern char* utfecpy(char*, char*, char*); | ||
| 98 | |||
| 99 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 100 | extern Rune* runestrchr(Rune*, Rune); | ||
| 101 | extern int runestrcmp(Rune*, Rune*); | ||
| 102 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 103 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 104 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 105 | extern Rune* runestrdup(Rune*); | ||
| 106 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 107 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 108 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 109 | extern long runestrlen(Rune*); | ||
| 110 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 111 | |||
| 112 | extern Rune tolowerrune(Rune); | ||
| 113 | extern Rune totitlerune(Rune); | ||
| 114 | extern Rune toupperrune(Rune); | ||
| 115 | extern int isalpharune(Rune); | ||
| 116 | extern int islowerrune(Rune); | ||
| 117 | extern int isspacerune(Rune); | ||
| 118 | extern int istitlerune(Rune); | ||
| 119 | extern int isupperrune(Rune); | ||
| 120 | |||
| 121 | /* | ||
| 122 | * malloc | ||
| 123 | */ | ||
| 124 | extern void* malloc(size_t); | ||
| 125 | extern void* mallocz(ulong, int); | ||
| 126 | extern void free(void*); | ||
| 127 | extern ulong msize(void*); | ||
| 128 | extern void* calloc(size_t, size_t); | ||
| 129 | extern void* realloc(void*, size_t); | ||
| 130 | extern void setmalloctag(void*, ulong); | ||
| 131 | extern void setrealloctag(void*, ulong); | ||
| 132 | extern ulong getmalloctag(void*); | ||
| 133 | extern ulong getrealloctag(void*); | ||
| 134 | extern void* malloctopoolblock(void*); | ||
| 135 | |||
| 136 | /* | ||
| 137 | * print routines | ||
| 138 | */ | ||
| 139 | typedef struct Fmt Fmt; | ||
| 140 | struct Fmt{ | ||
| 141 | uchar runes; /* output buffer is runes or chars? */ | ||
| 142 | void *start; /* of buffer */ | ||
| 143 | void *to; /* current place in the buffer */ | ||
| 144 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 145 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 146 | void *farg; /* to make flush a closure */ | ||
| 147 | int nfmt; /* num chars formatted so far */ | ||
| 148 | va_list args; /* args passed to dofmt */ | ||
| 149 | int r; /* % format Rune */ | ||
| 150 | int width; | ||
| 151 | int prec; | ||
| 152 | ulong flags; | ||
| 153 | }; | ||
| 154 | |||
| 155 | enum{ | ||
| 156 | FmtWidth = 1, | ||
| 157 | FmtLeft = FmtWidth << 1, | ||
| 158 | FmtPrec = FmtLeft << 1, | ||
| 159 | FmtSharp = FmtPrec << 1, | ||
| 160 | FmtSpace = FmtSharp << 1, | ||
| 161 | FmtSign = FmtSpace << 1, | ||
| 162 | FmtZero = FmtSign << 1, | ||
| 163 | FmtUnsigned = FmtZero << 1, | ||
| 164 | FmtShort = FmtUnsigned << 1, | ||
| 165 | FmtLong = FmtShort << 1, | ||
| 166 | FmtVLong = FmtLong << 1, | ||
| 167 | FmtComma = FmtVLong << 1, | ||
| 168 | FmtByte = FmtComma << 1, | ||
| 169 | |||
| 170 | FmtFlag = FmtByte << 1 | ||
| 171 | }; | ||
| 172 | |||
| 173 | extern int print(char*, ...); | ||
| 174 | extern char* seprint(char*, char*, char*, ...); | ||
| 175 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 176 | extern int snprint(char*, int, char*, ...); | ||
| 177 | extern int vsnprint(char*, int, char*, va_list); | ||
| 178 | extern char* smprint(char*, ...); | ||
| 179 | extern char* vsmprint(char*, va_list); | ||
| 180 | extern int sprint(char*, char*, ...); | ||
| 181 | extern int fprint(int, char*, ...); | ||
| 182 | extern int vfprint(int, char*, va_list); | ||
| 183 | |||
| 184 | extern int runesprint(Rune*, char*, ...); | ||
| 185 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 186 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 187 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 188 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 189 | extern Rune* runesmprint(char*, ...); | ||
| 190 | extern Rune* runevsmprint(char*, va_list); | ||
| 191 | |||
| 192 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 193 | extern int fmtfdflush(Fmt*); | ||
| 194 | extern int fmtstrinit(Fmt*); | ||
| 195 | extern char* fmtstrflush(Fmt*); | ||
| 196 | extern int runefmtstrinit(Fmt*); | ||
| 197 | extern Rune* runefmtstrflush(Fmt*); | ||
| 198 | |||
| 199 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 200 | extern int dofmt(Fmt*, char*); | ||
| 201 | extern int dorfmt(Fmt*, Rune*); | ||
| 202 | extern int fmtprint(Fmt*, char*, ...); | ||
| 203 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 204 | extern int fmtrune(Fmt*, int); | ||
| 205 | extern int fmtstrcpy(Fmt*, char*); | ||
| 206 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 207 | /* | ||
| 208 | * error string for %r | ||
| 209 | * supplied on per os basis, not part of fmt library | ||
| 210 | */ | ||
| 211 | extern int errfmt(Fmt *f); | ||
| 212 | |||
| 213 | /* | ||
| 214 | * quoted strings | ||
| 215 | */ | ||
| 216 | extern char *unquotestrdup(char*); | ||
| 217 | extern Rune *unquoterunestrdup(Rune*); | ||
| 218 | extern char *quotestrdup(char*); | ||
| 219 | extern Rune *quoterunestrdup(Rune*); | ||
| 220 | extern int quotestrfmt(Fmt*); | ||
| 221 | extern int quoterunestrfmt(Fmt*); | ||
| 222 | extern void quotefmtinstall(void); | ||
| 223 | extern int (*doquote)(int); | ||
| 224 | |||
| 225 | /* | ||
| 226 | * random number | ||
| 227 | */ | ||
| 228 | extern ulong truerand(void); | ||
| 229 | extern ulong ntruerand(ulong); | ||
| 230 | |||
| 231 | /* | ||
| 232 | * math | ||
| 233 | */ | ||
| 234 | extern int isNaN(double); | ||
| 235 | extern int isInf(double, int); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * Time-of-day | ||
| 239 | */ | ||
| 240 | |||
| 241 | typedef struct Tm Tm; | ||
| 242 | struct Tm { | ||
| 243 | int sec; | ||
| 244 | int min; | ||
| 245 | int hour; | ||
| 246 | int mday; | ||
| 247 | int mon; | ||
| 248 | int year; | ||
| 249 | int wday; | ||
| 250 | int yday; | ||
| 251 | char zone[4]; | ||
| 252 | int tzoff; | ||
| 253 | }; | ||
| 254 | extern vlong osnsec(void); | ||
| 255 | #define nsec osnsec | ||
| 256 | |||
| 257 | /* | ||
| 258 | * one-of-a-kind | ||
| 259 | */ | ||
| 260 | extern void _assert(char*); | ||
| 261 | extern double charstod(int(*)(void*), void*); | ||
| 262 | extern char* cleanname(char*); | ||
| 263 | //extern uintptr getcallerpc(void*); | ||
| 264 | extern int getfields(char*, char**, int, int, char*); | ||
| 265 | extern char* getuser(void); | ||
| 266 | extern char* getwd(char*, int); | ||
| 267 | extern double ipow10(int); | ||
| 268 | #define pow10 infpow10 | ||
| 269 | extern double pow10(int); | ||
| 270 | extern vlong strtoll(const char*, char**, int); | ||
| 271 | #define qsort infqsort | ||
| 272 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 273 | extern uvlong strtoull(const char*, char**, int); | ||
| 274 | extern void sysfatal(char*, ...); | ||
| 275 | extern int dec64(uchar*, int, char*, int); | ||
| 276 | extern int enc64(char*, int, uchar*, int); | ||
| 277 | extern int dec32(uchar*, int, char*, int); | ||
| 278 | extern int enc32(char*, int, uchar*, int); | ||
| 279 | extern int dec16(uchar*, int, char*, int); | ||
| 280 | extern int enc16(char*, int, uchar*, int); | ||
| 281 | extern int encodefmt(Fmt*); | ||
| 282 | |||
| 283 | /* | ||
| 284 | * synchronization | ||
| 285 | */ | ||
| 286 | typedef | ||
| 287 | struct Lock { | ||
| 288 | int val; | ||
| 289 | int pid; | ||
| 290 | } Lock; | ||
| 291 | |||
| 292 | extern int _tas(int*); | ||
| 293 | |||
| 294 | extern void lock(Lock*); | ||
| 295 | extern void unlock(Lock*); | ||
| 296 | extern int canlock(Lock*); | ||
| 297 | |||
| 298 | typedef struct QLock QLock; | ||
| 299 | struct QLock | ||
| 300 | { | ||
| 301 | Lock use; /* to access Qlock structure */ | ||
| 302 | Proc *head; /* next process waiting for object */ | ||
| 303 | Proc *tail; /* last process waiting for object */ | ||
| 304 | int locked; /* flag */ | ||
| 305 | }; | ||
| 306 | |||
| 307 | extern void qlock(QLock*); | ||
| 308 | extern void qunlock(QLock*); | ||
| 309 | extern int canqlock(QLock*); | ||
| 310 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 311 | |||
| 312 | typedef | ||
| 313 | struct RWLock | ||
| 314 | { | ||
| 315 | Lock l; /* Lock modify lock */ | ||
| 316 | QLock x; /* Mutual exclusion lock */ | ||
| 317 | QLock k; /* Lock for waiting writers */ | ||
| 318 | int readers; /* Count of readers in lock */ | ||
| 319 | } RWLock; | ||
| 320 | |||
| 321 | extern int canrlock(RWLock*); | ||
| 322 | extern int canwlock(RWLock*); | ||
| 323 | extern void rlock(RWLock*); | ||
| 324 | extern void runlock(RWLock*); | ||
| 325 | extern void wlock(RWLock*); | ||
| 326 | extern void wunlock(RWLock*); | ||
| 327 | |||
| 328 | /* | ||
| 329 | * network dialing | ||
| 330 | */ | ||
| 331 | #define NETPATHLEN 40 | ||
| 332 | |||
| 333 | /* | ||
| 334 | * system calls | ||
| 335 | * | ||
| 336 | */ | ||
| 337 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 338 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 339 | #define ERRMAX 128 /* max length of error string */ | ||
| 340 | |||
| 341 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 342 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 343 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 344 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 345 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 346 | #define MCACHE 0x0010 /* cache some data */ | ||
| 347 | #define MMASK 0x0017 /* all bits on */ | ||
| 348 | |||
| 349 | #define OREAD 0 /* open for read */ | ||
| 350 | #define OWRITE 1 /* write */ | ||
| 351 | #define ORDWR 2 /* read and write */ | ||
| 352 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 353 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 354 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 355 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 356 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 357 | |||
| 358 | #define AEXIST 0 /* accessible: exists */ | ||
| 359 | #define AEXEC 1 /* execute access */ | ||
| 360 | #define AWRITE 2 /* write access */ | ||
| 361 | #define AREAD 4 /* read access */ | ||
| 362 | |||
| 363 | /* bits in Qid.type */ | ||
| 364 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 365 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 366 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 367 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 368 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 369 | #define QTFILE 0x00 /* plain file */ | ||
| 370 | |||
| 371 | /* bits in Dir.mode */ | ||
| 372 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 373 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 374 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 375 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 376 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 377 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 378 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 379 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 380 | |||
| 381 | typedef | ||
| 382 | struct Qid | ||
| 383 | { | ||
| 384 | uvlong path; | ||
| 385 | ulong vers; | ||
| 386 | uchar type; | ||
| 387 | } Qid; | ||
| 388 | |||
| 389 | typedef | ||
| 390 | struct Dir { | ||
| 391 | /* system-modified data */ | ||
| 392 | ushort type; /* server type */ | ||
| 393 | uint dev; /* server subtype */ | ||
| 394 | /* file data */ | ||
| 395 | Qid qid; /* unique id from server */ | ||
| 396 | ulong mode; /* permissions */ | ||
| 397 | ulong atime; /* last read time */ | ||
| 398 | ulong mtime; /* last write time */ | ||
| 399 | vlong length; /* file length */ | ||
| 400 | char *name; /* last element of path */ | ||
| 401 | char *uid; /* owner name */ | ||
| 402 | char *gid; /* group name */ | ||
| 403 | char *muid; /* last modifier name */ | ||
| 404 | } Dir; | ||
| 405 | |||
| 406 | extern Dir* dirstat(char*); | ||
| 407 | extern Dir* dirfstat(int); | ||
| 408 | extern int dirwstat(char*, Dir*); | ||
| 409 | extern int dirfwstat(int, Dir*); | ||
| 410 | extern long dirread(int, Dir**); | ||
| 411 | extern void nulldir(Dir*); | ||
| 412 | extern long dirreadall(int, Dir**); | ||
| 413 | |||
| 414 | typedef | ||
| 415 | struct Waitmsg | ||
| 416 | { | ||
| 417 | int pid; /* of loved one */ | ||
| 418 | ulong time[3]; /* of loved one & descendants */ | ||
| 419 | char *msg; | ||
| 420 | } Waitmsg; | ||
| 421 | |||
| 422 | extern void _exits(char*); | ||
| 423 | |||
| 424 | extern void exits(char*); | ||
| 425 | extern int create(char*, int, int); | ||
| 426 | extern int errstr(char*, uint); | ||
| 427 | |||
| 428 | extern void perror(const char*); | ||
| 429 | extern long readn(int, void*, long); | ||
| 430 | extern int remove(const char*); | ||
| 431 | extern void rerrstr(char*, uint); | ||
| 432 | extern vlong seek(int, vlong, int); | ||
| 433 | extern int segflush(void*, ulong); | ||
| 434 | extern void werrstr(char*, ...); | ||
| 435 | |||
| 436 | extern char *argv0; | ||
| 437 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 438 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 439 | argc--, argv++) {\ | ||
| 440 | char *_args, *_argt;\ | ||
| 441 | Rune _argc;\ | ||
| 442 | _args = &argv[0][1];\ | ||
| 443 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 444 | argc--; argv++; break;\ | ||
| 445 | }\ | ||
| 446 | _argc = 0;\ | ||
| 447 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 448 | switch(_argc) | ||
| 449 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 450 | #define ARGF() (_argt=_args, _args="",\ | ||
| 451 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 452 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 453 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 454 | |||
| 455 | #define ARGC() _argc | ||
| 456 | |||
| 457 | /* | ||
| 458 | * Extensions for Inferno to basic libc.h | ||
| 459 | */ | ||
| 460 | |||
| 461 | #define setbinmode() | ||
| 462 | |||
| 463 | /* need the inline because the link register is not saved in a known location */ | ||
| 464 | static __inline uintptr getcallerpc(void* dummy) { | ||
| 465 | ulong lr; | ||
| 466 | __asm__( "mov %0, %%lr;" | ||
| 467 | : "=r" (lr) | ||
| 468 | ); | ||
| 469 | return lr; | ||
| 470 | } | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,37 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 9 | */ | ||
| 10 | typedef struct FPU FPU; | ||
| 11 | struct FPU | ||
| 12 | { | ||
| 13 | uchar env[18*8]; | ||
| 14 | }; | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Later versions of Linux seemed to need large stack for gethostbyname() | ||
| 18 | * so we had this at 128k, which is excessive. More recently, we've | ||
| 19 | * reduced it again after testing stack usage by gethostbyname. | ||
| 20 | */ | ||
| 21 | #define KSTACK (16 * 1024) | ||
| 22 | |||
| 23 | #ifndef USE_PTHREADS | ||
| 24 | static __inline Proc *getup(void) { | ||
| 25 | Proc *p; | ||
| 26 | __asm__( "mr %0, 1" : "=r" (p)); | ||
| 27 | return *(Proc **)((unsigned long)p & ~(KSTACK - 1)); | ||
| 28 | } | ||
| 29 | #else | ||
| 30 | extern Proc* getup(void); | ||
| 31 | #endif | ||
| 32 | |||
| 33 | #define up (getup()) | ||
| 34 | |||
| 35 | typedef sigjmp_buf osjmpbuf; | ||
| 36 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| 37 | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | /* | ||
| 2 | * Linux PPC | ||
| 3 | * Mimic Plan9 floating point support | ||
| 4 | */ | ||
| 5 | |||
| 6 | static __inline__ ulong | ||
| 7 | getfcr(void) | ||
| 8 | { | ||
| 9 | float fpscr; | ||
| 10 | |||
| 11 | __asm__ __volatile__ ("mffs %0" : "=&f" (fpscr):); | ||
| 12 | |||
| 13 | return (ulong)fpscr; | ||
| 14 | } | ||
| 15 | |||
| 16 | static __inline__ ulong | ||
| 17 | getfsr(void) | ||
| 18 | { | ||
| 19 | float fpscr; | ||
| 20 | |||
| 21 | __asm__ __volatile__ ("mffs %0" : "=&f" (fpscr):); | ||
| 22 | |||
| 23 | return (ulong) fpscr; | ||
| 24 | } | ||
| 25 | |||
| 26 | static __inline__ void | ||
| 27 | setfsr(ulong fsr) | ||
| 28 | { | ||
| 29 | float t = (float) fsr; | ||
| 30 | |||
| 31 | __asm__ __volatile__("mtfsf 0xff, %0" : : "f" (t) ); | ||
| 32 | } | ||
| 33 | |||
| 34 | static __inline__ void | ||
| 35 | setfcr(ulong fcr) | ||
| 36 | { | ||
| 37 | float t = (float) fcr; | ||
| 38 | |||
| 39 | __asm__ __volatile__("mtfsf 0xff, %0" : : "f" (t) ); | ||
| 40 | } | ||
| 41 | |||
| 42 | /* FPSCR */ | ||
| 43 | #define FPSFX (1<<31) /* exception summary (sticky) */ | ||
| 44 | #define FPSEX (1<<30) /* enabled exception summary */ | ||
| 45 | #define FPSVX (1<<29) /* invalid operation exception summary */ | ||
| 46 | #define FPSOX (1<<28) /* overflow exception OX (sticky) */ | ||
| 47 | #define FPSUX (1<<27) /* underflow exception UX (sticky) */ | ||
| 48 | #define FPSZX (1<<26) /* zero divide exception ZX (sticky) */ | ||
| 49 | #define FPSXX (1<<25) /* inexact exception XX (sticky) */ | ||
| 50 | #define FPSVXSNAN (1<<24) /* invalid operation exception for SNaN (sticky) */ | ||
| 51 | #define FPSVXISI (1<<23) /* invalid operation exception for ∞-∞ (sticky) */ | ||
| 52 | #define FPSVXIDI (1<<22) /* invalid operation exception for ∞/∞ (sticky) */ | ||
| 53 | #define FPSVXZDZ (1<<21) /* invalid operation exception for 0/0 (sticky) */ | ||
| 54 | #define FPSVXIMZ (1<<20) /* invalid operation exception for ∞*0 (sticky) */ | ||
| 55 | #define FPSVXVC (1<<19) /* invalid operation exception for invalid compare (sticky) */ | ||
| 56 | #define FPSFR (1<<18) /* fraction rounded */ | ||
| 57 | #define FPSFI (1<<17) /* fraction inexact */ | ||
| 58 | #define FPSFPRF (1<<16) /* floating point result class */ | ||
| 59 | #define FPSFPCC (0xF<<12) /* <, >, =, unordered */ | ||
| 60 | #define FPVXCVI (1<<8) /* enable exception for invalid integer convert (sticky) */ | ||
| 61 | |||
| 62 | /* FCR */ | ||
| 63 | #define FPVE (1<<7) /* invalid operation exception enable */ | ||
| 64 | #define FPOVFL (1<<6) /* enable overflow exceptions */ | ||
| 65 | #define FPUNFL (1<<5) /* enable underflow */ | ||
| 66 | #define FPZDIV (1<<4) /* enable zero divide */ | ||
| 67 | #define FPINEX (1<<3) /* enable inexact exceptions */ | ||
| 68 | #define FPRMASK (3<<0) /* rounding mode */ | ||
| 69 | #define FPRNR (0<<0) | ||
| 70 | #define FPRZ (1<<0) | ||
| 71 | #define FPRPINF (2<<0) | ||
| 72 | #define FPRNINF (3<<0) | ||
| 73 | #define FPPEXT 0 | ||
| 74 | #define FPPSGL 0 | ||
| 75 | #define FPPDBL 0 | ||
| 76 | #define FPPMASK 0 | ||
| 77 | #define FPINVAL FPVE | ||
| 78 | /* FSR */ | ||
| 79 | #define FPAOVFL FPSOX | ||
| 80 | #define FPAINEX FPSXX | ||
| 81 | #define FPAUNFL FPSUX | ||
| 82 | #define FPAZDIV FPSZX | ||
| 83 | #define FPAINVAL FPSVX | ||
| @@ -0,0 +1,463 @@ | |||
| 1 | /* define _BSD_SOURCE to use ISO C, POSIX, and 4.3BSD things. */ | ||
| 2 | #define USE_PTHREADS | ||
| 3 | #ifndef _BSD_SOURCE | ||
| 4 | #define _BSD_SOURCE | ||
| 5 | #endif | ||
| 6 | #define _XOPEN_SOURCE 500 | ||
| 7 | #define _LARGEFILE_SOURCE 1 | ||
| 8 | #define _LARGEFILE64_SOURCE 1 | ||
| 9 | #define _FILE_OFFSET_BITS 64 | ||
| 10 | #ifdef USE_PTHREADS | ||
| 11 | #define _REENTRANT 1 | ||
| 12 | #endif | ||
| 13 | #include <features.h> | ||
| 14 | #include <sys/types.h> | ||
| 15 | #include <stdlib.h> | ||
| 16 | #include <stdarg.h> | ||
| 17 | #define sync __os_sync | ||
| 18 | #include <unistd.h> | ||
| 19 | #undef sync | ||
| 20 | #include <errno.h> | ||
| 21 | #define __NO_STRING_INLINES | ||
| 22 | #include <string.h> | ||
| 23 | #include "math.h" | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <setjmp.h> | ||
| 26 | #include <float.h> | ||
| 27 | #include <endian.h> | ||
| 28 | |||
| 29 | #define getwd infgetwd | ||
| 30 | |||
| 31 | #ifndef EMU | ||
| 32 | typedef struct Proc Proc; | ||
| 33 | #endif | ||
| 34 | |||
| 35 | /* | ||
| 36 | * math module dtoa | ||
| 37 | * #define __LITTLE_ENDIAN /usr/include/endian.h under linux | ||
| 38 | */ | ||
| 39 | #undef __LITTLE_ENDIAN | ||
| 40 | |||
| 41 | #define nil ((void*)0) | ||
| 42 | |||
| 43 | typedef unsigned char uchar; | ||
| 44 | typedef signed char schar; | ||
| 45 | typedef unsigned short Rune; | ||
| 46 | typedef long long int vlong; | ||
| 47 | typedef unsigned long long int uvlong; | ||
| 48 | typedef unsigned int u32int; | ||
| 49 | typedef uvlong u64int; | ||
| 50 | |||
| 51 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 52 | typedef unsigned short u16int; | ||
| 53 | typedef unsigned char u8int; | ||
| 54 | typedef unsigned long uintptr; | ||
| 55 | |||
| 56 | #define USED(x) if(x){}else{} | ||
| 57 | #define SET(x) | ||
| 58 | |||
| 59 | #undef nelem | ||
| 60 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 61 | #undef offsetof | ||
| 62 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 63 | #undef assert | ||
| 64 | #define assert(x) if(x){}else _assert("x") | ||
| 65 | |||
| 66 | /* | ||
| 67 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 68 | */ | ||
| 69 | |||
| 70 | extern char* strecpy(char*, char*, char*); | ||
| 71 | extern char* strdup(const char*); | ||
| 72 | extern int cistrncmp(char*, char*, int); | ||
| 73 | extern int cistrcmp(char*, char*); | ||
| 74 | extern char* cistrstr(char*, char*); | ||
| 75 | extern int tokenize(char*, char**, int); | ||
| 76 | |||
| 77 | enum | ||
| 78 | { | ||
| 79 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 80 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 81 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 82 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 83 | }; | ||
| 84 | |||
| 85 | /* | ||
| 86 | * rune routines | ||
| 87 | */ | ||
| 88 | extern int runetochar(char*, Rune*); | ||
| 89 | extern int chartorune(Rune*, char*); | ||
| 90 | extern int runelen(long); | ||
| 91 | extern int runenlen(Rune*, int); | ||
| 92 | extern int fullrune(char*, int); | ||
| 93 | extern int utflen(char*); | ||
| 94 | extern int utfnlen(char*, long); | ||
| 95 | extern char* utfrune(char*, long); | ||
| 96 | extern char* utfrrune(char*, long); | ||
| 97 | extern char* utfutf(char*, char*); | ||
| 98 | extern char* utfecpy(char*, char*, char*); | ||
| 99 | |||
| 100 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 101 | extern Rune* runestrchr(Rune*, Rune); | ||
| 102 | extern int runestrcmp(Rune*, Rune*); | ||
| 103 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 104 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 105 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 106 | extern Rune* runestrdup(Rune*); | ||
| 107 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 108 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 109 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 110 | extern long runestrlen(Rune*); | ||
| 111 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 112 | |||
| 113 | extern Rune tolowerrune(Rune); | ||
| 114 | extern Rune totitlerune(Rune); | ||
| 115 | extern Rune toupperrune(Rune); | ||
| 116 | extern int isalpharune(Rune); | ||
| 117 | extern int islowerrune(Rune); | ||
| 118 | extern int isspacerune(Rune); | ||
| 119 | extern int istitlerune(Rune); | ||
| 120 | extern int isupperrune(Rune); | ||
| 121 | |||
| 122 | /* | ||
| 123 | * malloc | ||
| 124 | */ | ||
| 125 | extern void* malloc(size_t); | ||
| 126 | extern void* mallocz(ulong, int); | ||
| 127 | extern void free(void*); | ||
| 128 | extern ulong msize(void*); | ||
| 129 | extern void* calloc(size_t, size_t); | ||
| 130 | extern void* realloc(void*, size_t); | ||
| 131 | extern void setmalloctag(void*, ulong); | ||
| 132 | extern void setrealloctag(void*, ulong); | ||
| 133 | extern ulong getmalloctag(void*); | ||
| 134 | extern ulong getrealloctag(void*); | ||
| 135 | extern void* malloctopoolblock(void*); | ||
| 136 | |||
| 137 | /* | ||
| 138 | * print routines | ||
| 139 | */ | ||
| 140 | typedef struct Fmt Fmt; | ||
| 141 | struct Fmt{ | ||
| 142 | uchar runes; /* output buffer is runes or chars? */ | ||
| 143 | void *start; /* of buffer */ | ||
| 144 | void *to; /* current place in the buffer */ | ||
| 145 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 146 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 147 | void *farg; /* to make flush a closure */ | ||
| 148 | int nfmt; /* num chars formatted so far */ | ||
| 149 | va_list args; /* args passed to dofmt */ | ||
| 150 | int r; /* % format Rune */ | ||
| 151 | int width; | ||
| 152 | int prec; | ||
| 153 | ulong flags; | ||
| 154 | }; | ||
| 155 | |||
| 156 | enum{ | ||
| 157 | FmtWidth = 1, | ||
| 158 | FmtLeft = FmtWidth << 1, | ||
| 159 | FmtPrec = FmtLeft << 1, | ||
| 160 | FmtSharp = FmtPrec << 1, | ||
| 161 | FmtSpace = FmtSharp << 1, | ||
| 162 | FmtSign = FmtSpace << 1, | ||
| 163 | FmtZero = FmtSign << 1, | ||
| 164 | FmtUnsigned = FmtZero << 1, | ||
| 165 | FmtShort = FmtUnsigned << 1, | ||
| 166 | FmtLong = FmtShort << 1, | ||
| 167 | FmtVLong = FmtLong << 1, | ||
| 168 | FmtComma = FmtVLong << 1, | ||
| 169 | FmtByte = FmtComma << 1, | ||
| 170 | |||
| 171 | FmtFlag = FmtByte << 1 | ||
| 172 | }; | ||
| 173 | |||
| 174 | extern int print(char*, ...); | ||
| 175 | extern char* seprint(char*, char*, char*, ...); | ||
| 176 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 177 | extern int snprint(char*, int, char*, ...); | ||
| 178 | extern int vsnprint(char*, int, char*, va_list); | ||
| 179 | extern char* smprint(char*, ...); | ||
| 180 | extern char* vsmprint(char*, va_list); | ||
| 181 | extern int sprint(char*, char*, ...); | ||
| 182 | extern int fprint(int, char*, ...); | ||
| 183 | extern int vfprint(int, char*, va_list); | ||
| 184 | |||
| 185 | extern int runesprint(Rune*, char*, ...); | ||
| 186 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 187 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 188 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 189 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 190 | extern Rune* runesmprint(char*, ...); | ||
| 191 | extern Rune* runevsmprint(char*, va_list); | ||
| 192 | |||
| 193 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 194 | extern int fmtfdflush(Fmt*); | ||
| 195 | extern int fmtstrinit(Fmt*); | ||
| 196 | extern char* fmtstrflush(Fmt*); | ||
| 197 | extern int runefmtstrinit(Fmt*); | ||
| 198 | extern Rune* runefmtstrflush(Fmt*); | ||
| 199 | |||
| 200 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 201 | extern int dofmt(Fmt*, char*); | ||
| 202 | extern int dorfmt(Fmt*, Rune*); | ||
| 203 | extern int fmtprint(Fmt*, char*, ...); | ||
| 204 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 205 | extern int fmtrune(Fmt*, int); | ||
| 206 | extern int fmtstrcpy(Fmt*, char*); | ||
| 207 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 208 | /* | ||
| 209 | * error string for %r | ||
| 210 | * supplied on per os basis, not part of fmt library | ||
| 211 | */ | ||
| 212 | extern int errfmt(Fmt *f); | ||
| 213 | |||
| 214 | /* | ||
| 215 | * quoted strings | ||
| 216 | */ | ||
| 217 | extern char *unquotestrdup(char*); | ||
| 218 | extern Rune *unquoterunestrdup(Rune*); | ||
| 219 | extern char *quotestrdup(char*); | ||
| 220 | extern Rune *quoterunestrdup(Rune*); | ||
| 221 | extern int quotestrfmt(Fmt*); | ||
| 222 | extern int quoterunestrfmt(Fmt*); | ||
| 223 | extern void quotefmtinstall(void); | ||
| 224 | extern int (*doquote)(int); | ||
| 225 | |||
| 226 | /* | ||
| 227 | * random number | ||
| 228 | */ | ||
| 229 | extern ulong truerand(void); | ||
| 230 | extern ulong ntruerand(ulong); | ||
| 231 | |||
| 232 | /* | ||
| 233 | * math | ||
| 234 | */ | ||
| 235 | extern int isNaN(double); | ||
| 236 | extern int isInf(double, int); | ||
| 237 | |||
| 238 | /* | ||
| 239 | * Time-of-day | ||
| 240 | */ | ||
| 241 | |||
| 242 | typedef struct Tm Tm; | ||
| 243 | struct Tm { | ||
| 244 | int sec; | ||
| 245 | int min; | ||
| 246 | int hour; | ||
| 247 | int mday; | ||
| 248 | int mon; | ||
| 249 | int year; | ||
| 250 | int wday; | ||
| 251 | int yday; | ||
| 252 | char zone[4]; | ||
| 253 | int tzoff; | ||
| 254 | }; | ||
| 255 | extern vlong osnsec(void); | ||
| 256 | #define nsec osnsec | ||
| 257 | |||
| 258 | /* | ||
| 259 | * one-of-a-kind | ||
| 260 | */ | ||
| 261 | extern void _assert(char*); | ||
| 262 | extern double charstod(int(*)(void*), void*); | ||
| 263 | extern char* cleanname(char*); | ||
| 264 | extern uintptr getcallerpc(void*); | ||
| 265 | extern int getfields(char*, char**, int, int, char*); | ||
| 266 | extern char* getuser(void); | ||
| 267 | extern char* getwd(char*, int); | ||
| 268 | extern double ipow10(int); | ||
| 269 | #define pow10 infpow10 | ||
| 270 | extern double pow10(int); | ||
| 271 | extern vlong strtoll(const char*, char**, int); | ||
| 272 | #define qsort infqsort | ||
| 273 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 274 | extern uvlong strtoull(const char*, char**, int); | ||
| 275 | extern void sysfatal(char*, ...); | ||
| 276 | extern int dec64(uchar*, int, char*, int); | ||
| 277 | extern int enc64(char*, int, uchar*, int); | ||
| 278 | extern int dec32(uchar*, int, char*, int); | ||
| 279 | extern int enc32(char*, int, uchar*, int); | ||
| 280 | extern int dec16(uchar*, int, char*, int); | ||
| 281 | extern int enc16(char*, int, uchar*, int); | ||
| 282 | extern int encodefmt(Fmt*); | ||
| 283 | |||
| 284 | /* | ||
| 285 | * synchronization | ||
| 286 | */ | ||
| 287 | typedef | ||
| 288 | struct Lock { | ||
| 289 | int val; | ||
| 290 | int pid; | ||
| 291 | } Lock; | ||
| 292 | |||
| 293 | extern int _tas(int*); | ||
| 294 | |||
| 295 | extern void lock(Lock*); | ||
| 296 | extern void unlock(Lock*); | ||
| 297 | extern int canlock(Lock*); | ||
| 298 | |||
| 299 | typedef struct QLock QLock; | ||
| 300 | struct QLock | ||
| 301 | { | ||
| 302 | Lock use; /* to access Qlock structure */ | ||
| 303 | Proc *head; /* next process waiting for object */ | ||
| 304 | Proc *tail; /* last process waiting for object */ | ||
| 305 | int locked; /* flag */ | ||
| 306 | }; | ||
| 307 | |||
| 308 | extern void qlock(QLock*); | ||
| 309 | extern void qunlock(QLock*); | ||
| 310 | extern int canqlock(QLock*); | ||
| 311 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 312 | |||
| 313 | typedef | ||
| 314 | struct RWLock | ||
| 315 | { | ||
| 316 | Lock l; /* Lock modify lock */ | ||
| 317 | QLock x; /* Mutual exclusion lock */ | ||
| 318 | QLock k; /* Lock for waiting writers */ | ||
| 319 | int readers; /* Count of readers in lock */ | ||
| 320 | } RWLock; | ||
| 321 | |||
| 322 | extern int canrlock(RWLock*); | ||
| 323 | extern int canwlock(RWLock*); | ||
| 324 | extern void rlock(RWLock*); | ||
| 325 | extern void runlock(RWLock*); | ||
| 326 | extern void wlock(RWLock*); | ||
| 327 | extern void wunlock(RWLock*); | ||
| 328 | |||
| 329 | /* | ||
| 330 | * network dialing | ||
| 331 | */ | ||
| 332 | #define NETPATHLEN 40 | ||
| 333 | |||
| 334 | /* | ||
| 335 | * system calls | ||
| 336 | * | ||
| 337 | */ | ||
| 338 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 339 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 340 | #define ERRMAX 128 /* max length of error string */ | ||
| 341 | |||
| 342 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 343 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 344 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 345 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 346 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 347 | #define MCACHE 0x0010 /* cache some data */ | ||
| 348 | #define MMASK 0x0017 /* all bits on */ | ||
| 349 | |||
| 350 | #define OREAD 0 /* open for read */ | ||
| 351 | #define OWRITE 1 /* write */ | ||
| 352 | #define ORDWR 2 /* read and write */ | ||
| 353 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 354 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 355 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 356 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 357 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 358 | |||
| 359 | #define AEXIST 0 /* accessible: exists */ | ||
| 360 | #define AEXEC 1 /* execute access */ | ||
| 361 | #define AWRITE 2 /* write access */ | ||
| 362 | #define AREAD 4 /* read access */ | ||
| 363 | |||
| 364 | /* bits in Qid.type */ | ||
| 365 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 366 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 367 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 368 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 369 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 370 | #define QTFILE 0x00 /* plain file */ | ||
| 371 | |||
| 372 | /* bits in Dir.mode */ | ||
| 373 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 374 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 375 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 376 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 377 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 378 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 379 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 380 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 381 | |||
| 382 | typedef | ||
| 383 | struct Qid | ||
| 384 | { | ||
| 385 | uvlong path; | ||
| 386 | ulong vers; | ||
| 387 | uchar type; | ||
| 388 | } Qid; | ||
| 389 | |||
| 390 | typedef | ||
| 391 | struct Dir { | ||
| 392 | /* system-modified data */ | ||
| 393 | ushort type; /* server type */ | ||
| 394 | uint dev; /* server subtype */ | ||
| 395 | /* file data */ | ||
| 396 | Qid qid; /* unique id from server */ | ||
| 397 | ulong mode; /* permissions */ | ||
| 398 | ulong atime; /* last read time */ | ||
| 399 | ulong mtime; /* last write time */ | ||
| 400 | vlong length; /* file length */ | ||
| 401 | char *name; /* last element of path */ | ||
| 402 | char *uid; /* owner name */ | ||
| 403 | char *gid; /* group name */ | ||
| 404 | char *muid; /* last modifier name */ | ||
| 405 | } Dir; | ||
| 406 | |||
| 407 | extern Dir* dirstat(char*); | ||
| 408 | extern Dir* dirfstat(int); | ||
| 409 | extern int dirwstat(char*, Dir*); | ||
| 410 | extern int dirfwstat(int, Dir*); | ||
| 411 | extern long dirread(int, Dir**); | ||
| 412 | extern void nulldir(Dir*); | ||
| 413 | extern long dirreadall(int, Dir**); | ||
| 414 | |||
| 415 | typedef | ||
| 416 | struct Waitmsg | ||
| 417 | { | ||
| 418 | int pid; /* of loved one */ | ||
| 419 | ulong time[3]; /* of loved one & descendants */ | ||
| 420 | char *msg; | ||
| 421 | } Waitmsg; | ||
| 422 | |||
| 423 | extern void _exits(char*); | ||
| 424 | |||
| 425 | extern void exits(char*); | ||
| 426 | extern int create(char*, int, int); | ||
| 427 | extern int errstr(char*, uint); | ||
| 428 | |||
| 429 | extern void perror(const char*); | ||
| 430 | extern long readn(int, void*, long); | ||
| 431 | extern int remove(const char*); | ||
| 432 | extern void rerrstr(char*, uint); | ||
| 433 | extern vlong seek(int, vlong, int); | ||
| 434 | extern int segflush(void*, ulong); | ||
| 435 | extern void werrstr(char*, ...); | ||
| 436 | |||
| 437 | extern char *argv0; | ||
| 438 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 439 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 440 | argc--, argv++) {\ | ||
| 441 | char *_args, *_argt;\ | ||
| 442 | Rune _argc;\ | ||
| 443 | _args = &argv[0][1];\ | ||
| 444 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 445 | argc--; argv++; break;\ | ||
| 446 | }\ | ||
| 447 | _argc = 0;\ | ||
| 448 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 449 | switch(_argc) | ||
| 450 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 451 | #define ARGF() (_argt=_args, _args="",\ | ||
| 452 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 453 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 454 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 455 | |||
| 456 | #define ARGC() _argc | ||
| 457 | |||
| 458 | /* | ||
| 459 | * Extensions for Inferno to basic libc.h | ||
| 460 | */ | ||
| 461 | |||
| 462 | #define setbinmode() | ||
| 463 | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 9 | */ | ||
| 10 | typedef struct FPU FPU; | ||
| 11 | struct FPU | ||
| 12 | { | ||
| 13 | uchar env[28]; | ||
| 14 | }; | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Later versions of Linux seemed to need large stack for gethostbyname() | ||
| 18 | * so we had this at 128k, which is excessive. More recently, we've | ||
| 19 | * reduced it again after testing stack usage by gethostbyname. | ||
| 20 | */ | ||
| 21 | #define KSTACK (16 * 1024) | ||
| 22 | |||
| 23 | #ifndef USE_PTHREADS | ||
| 24 | static __inline Proc *getup(void) { | ||
| 25 | Proc *p; | ||
| 26 | __asm__( "move %0, $29\n\t" | ||
| 27 | : "=r" (p) | ||
| 28 | ); | ||
| 29 | return *(Proc **)((unsigned long)p & ~(KSTACK - 1)); | ||
| 30 | } | ||
| 31 | #else | ||
| 32 | extern Proc* getup(void); | ||
| 33 | #endif | ||
| 34 | |||
| 35 | #define up (getup()) | ||
| 36 | |||
| 37 | typedef sigjmp_buf osjmpbuf; | ||
| 38 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| 39 | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | /* FCR */ | ||
| 2 | #define FCRBITS 0x00000F83 | ||
| 3 | #define FPINEX (1<<7) | ||
| 4 | #define FPUNFL (1<<8) | ||
| 5 | #define FPOVFL (1<<9) | ||
| 6 | #define FPZDIV (1<<10) | ||
| 7 | #define FPINVAL (1<<11) | ||
| 8 | #define FPRNR (0<<0) | ||
| 9 | #define FPRZ (1<<0) | ||
| 10 | #define FPRPINF (2<<0) | ||
| 11 | #define FPRNINF (3<<0) | ||
| 12 | #define FPRMASK (3<<0) | ||
| 13 | #define FPPEXT 0 | ||
| 14 | #define FPPSGL 0 | ||
| 15 | #define FPPDBL 0 | ||
| 16 | #define FPPMASK 0 | ||
| 17 | /* FSR */ | ||
| 18 | #define FSRBITS 0x0003F07C | ||
| 19 | #define FPAINEX (1<<2) | ||
| 20 | #define FPAOVFL (1<<4) | ||
| 21 | #define FPAUNFL (1<<3) | ||
| 22 | #define FPAZDIV (1<<5) | ||
| 23 | #define FPAINVAL (1<<6) | ||
| 24 | |||
| 25 | /* | ||
| 26 | * Linux mips fpu support | ||
| 27 | * Mimic Plan9 floating point support | ||
| 28 | */ | ||
| 29 | |||
| 30 | static void | ||
| 31 | setfcr(ulong fcr) | ||
| 32 | { | ||
| 33 | __asm__("ctc1 %0,$31\n" | ||
| 34 | : :"r" (fcr) | ||
| 35 | ); | ||
| 36 | } | ||
| 37 | |||
| 38 | static ulong | ||
| 39 | getfcr(void) | ||
| 40 | { | ||
| 41 | ulong fcr = 0; | ||
| 42 | __asm__("cfc1 %0,$31\n" | ||
| 43 | : "=r" (fcr) | ||
| 44 | ); | ||
| 45 | fcr &= FCRBITS; | ||
| 46 | return fcr; | ||
| 47 | } | ||
| 48 | |||
| 49 | static ulong | ||
| 50 | getfsr(void) | ||
| 51 | { | ||
| 52 | ulong fsr = 0; | ||
| 53 | __asm__("cfc1 %0,$31\n" | ||
| 54 | : "=r" (fsr) | ||
| 55 | ); | ||
| 56 | fsr &= FSRBITS; | ||
| 57 | return fsr; | ||
| 58 | } | ||
| 59 | |||
| 60 | static void | ||
| 61 | setfsr(ulong fsr) | ||
| 62 | { | ||
| 63 | fsr |= getfcr(); | ||
| 64 | setfcr(getfcr()|fsr); | ||
| 65 | } | ||
| @@ -0,0 +1,464 @@ | |||
| 1 | /* define _BSD_SOURCE to use ISO C, POSIX, and 4.3BSD things. */ | ||
| 2 | #define USE_PTHREADS | ||
| 3 | #ifndef _BSD_SOURCE | ||
| 4 | #define _BSD_SOURCE | ||
| 5 | #endif | ||
| 6 | #define _LARGEFILE_SOURCE 1 | ||
| 7 | #define _LARGEFILE64_SOURCE 1 | ||
| 8 | #define _FILE_OFFSET_BITS 64 | ||
| 9 | #include <features.h> | ||
| 10 | #include <sys/types.h> | ||
| 11 | #include <stdlib.h> | ||
| 12 | #include <stdarg.h> | ||
| 13 | #define sync __os_sync | ||
| 14 | #include <unistd.h> | ||
| 15 | #undef sync | ||
| 16 | #include <errno.h> | ||
| 17 | #define __NO_STRING_INLINES | ||
| 18 | #include <string.h> | ||
| 19 | #include "math.h" | ||
| 20 | #include <fcntl.h> | ||
| 21 | #include <setjmp.h> | ||
| 22 | #include <float.h> | ||
| 23 | #include <endian.h> | ||
| 24 | |||
| 25 | #define getwd infgetwd | ||
| 26 | |||
| 27 | #ifndef EMU | ||
| 28 | typedef struct Proc Proc; | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* | ||
| 32 | * math module dtoa | ||
| 33 | * #define __LITTLE_ENDIAN according to target under linux | ||
| 34 | */ | ||
| 35 | |||
| 36 | #ifdef __MIPSEB__ | ||
| 37 | #undef __LITTLE_ENDIAN | ||
| 38 | #else | ||
| 39 | #define __LITTLE_ENDIAN 1234 | ||
| 40 | #endif | ||
| 41 | |||
| 42 | #define nil ((void*)0) | ||
| 43 | |||
| 44 | typedef unsigned char uchar; | ||
| 45 | typedef signed char schar; | ||
| 46 | typedef unsigned short Rune; | ||
| 47 | typedef long long int vlong; | ||
| 48 | typedef unsigned long long int uvlong; | ||
| 49 | typedef unsigned int u32int; | ||
| 50 | typedef uvlong u64int; | ||
| 51 | |||
| 52 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 53 | typedef unsigned short u16int; | ||
| 54 | typedef unsigned char u8int; | ||
| 55 | typedef unsigned long uintptr; | ||
| 56 | |||
| 57 | #define USED(x) if(x){}else{} | ||
| 58 | #define SET(x) | ||
| 59 | |||
| 60 | #undef nelem | ||
| 61 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 62 | #undef offsetof | ||
| 63 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 64 | #undef assert | ||
| 65 | #define assert(x) if(x){}else _assert("x") | ||
| 66 | |||
| 67 | /* | ||
| 68 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 69 | */ | ||
| 70 | |||
| 71 | extern char* strecpy(char*, char*, char*); | ||
| 72 | extern char* strdup(const char*); | ||
| 73 | extern int cistrncmp(char*, char*, int); | ||
| 74 | extern int cistrcmp(char*, char*); | ||
| 75 | extern char* cistrstr(char*, char*); | ||
| 76 | extern int tokenize(char*, char**, int); | ||
| 77 | |||
| 78 | enum | ||
| 79 | { | ||
| 80 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 81 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 82 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 83 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 84 | }; | ||
| 85 | |||
| 86 | /* | ||
| 87 | * rune routines | ||
| 88 | */ | ||
| 89 | extern int runetochar(char*, Rune*); | ||
| 90 | extern int chartorune(Rune*, char*); | ||
| 91 | extern int runelen(long); | ||
| 92 | extern int runenlen(Rune*, int); | ||
| 93 | extern int fullrune(char*, int); | ||
| 94 | extern int utflen(char*); | ||
| 95 | extern int utfnlen(char*, long); | ||
| 96 | extern char* utfrune(char*, long); | ||
| 97 | extern char* utfrrune(char*, long); | ||
| 98 | extern char* utfutf(char*, char*); | ||
| 99 | extern char* utfecpy(char*, char*, char*); | ||
| 100 | |||
| 101 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 102 | extern Rune* runestrchr(Rune*, Rune); | ||
| 103 | extern int runestrcmp(Rune*, Rune*); | ||
| 104 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 105 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 106 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 107 | extern Rune* runestrdup(Rune*); | ||
| 108 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 109 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 110 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 111 | extern long runestrlen(Rune*); | ||
| 112 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 113 | |||
| 114 | extern Rune tolowerrune(Rune); | ||
| 115 | extern Rune totitlerune(Rune); | ||
| 116 | extern Rune toupperrune(Rune); | ||
| 117 | extern int isalpharune(Rune); | ||
| 118 | extern int islowerrune(Rune); | ||
| 119 | extern int isspacerune(Rune); | ||
| 120 | extern int istitlerune(Rune); | ||
| 121 | extern int isupperrune(Rune); | ||
| 122 | |||
| 123 | /* | ||
| 124 | * malloc | ||
| 125 | */ | ||
| 126 | extern void* malloc(size_t); | ||
| 127 | extern void* mallocz(ulong, int); | ||
| 128 | extern void free(void*); | ||
| 129 | extern ulong msize(void*); | ||
| 130 | extern void* calloc(size_t, size_t); | ||
| 131 | extern void* realloc(void*, size_t); | ||
| 132 | extern void setmalloctag(void*, ulong); | ||
| 133 | extern void setrealloctag(void*, ulong); | ||
| 134 | extern ulong getmalloctag(void*); | ||
| 135 | extern ulong getrealloctag(void*); | ||
| 136 | extern void* malloctopoolblock(void*); | ||
| 137 | |||
| 138 | /* | ||
| 139 | * print routines | ||
| 140 | */ | ||
| 141 | typedef struct Fmt Fmt; | ||
| 142 | struct Fmt{ | ||
| 143 | uchar runes; /* output buffer is runes or chars? */ | ||
| 144 | void *start; /* of buffer */ | ||
| 145 | void *to; /* current place in the buffer */ | ||
| 146 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 147 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 148 | void *farg; /* to make flush a closure */ | ||
| 149 | int nfmt; /* num chars formatted so far */ | ||
| 150 | va_list args; /* args passed to dofmt */ | ||
| 151 | int r; /* % format Rune */ | ||
| 152 | int width; | ||
| 153 | int prec; | ||
| 154 | ulong flags; | ||
| 155 | }; | ||
| 156 | |||
| 157 | enum{ | ||
| 158 | FmtWidth = 1, | ||
| 159 | FmtLeft = FmtWidth << 1, | ||
| 160 | FmtPrec = FmtLeft << 1, | ||
| 161 | FmtSharp = FmtPrec << 1, | ||
| 162 | FmtSpace = FmtSharp << 1, | ||
| 163 | FmtSign = FmtSpace << 1, | ||
| 164 | FmtZero = FmtSign << 1, | ||
| 165 | FmtUnsigned = FmtZero << 1, | ||
| 166 | FmtShort = FmtUnsigned << 1, | ||
| 167 | FmtLong = FmtShort << 1, | ||
| 168 | FmtVLong = FmtLong << 1, | ||
| 169 | FmtComma = FmtVLong << 1, | ||
| 170 | FmtByte = FmtComma << 1, | ||
| 171 | |||
| 172 | FmtFlag = FmtByte << 1 | ||
| 173 | }; | ||
| 174 | |||
| 175 | extern int print(char*, ...); | ||
| 176 | extern char* seprint(char*, char*, char*, ...); | ||
| 177 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 178 | extern int snprint(char*, int, char*, ...); | ||
| 179 | extern int vsnprint(char*, int, char*, va_list); | ||
| 180 | extern char* smprint(char*, ...); | ||
| 181 | extern char* vsmprint(char*, va_list); | ||
| 182 | extern int sprint(char*, char*, ...); | ||
| 183 | extern int fprint(int, char*, ...); | ||
| 184 | extern int vfprint(int, char*, va_list); | ||
| 185 | |||
| 186 | extern int runesprint(Rune*, char*, ...); | ||
| 187 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 188 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 189 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 190 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 191 | extern Rune* runesmprint(char*, ...); | ||
| 192 | extern Rune* runevsmprint(char*, va_list); | ||
| 193 | |||
| 194 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 195 | extern int fmtfdflush(Fmt*); | ||
| 196 | extern int fmtstrinit(Fmt*); | ||
| 197 | extern char* fmtstrflush(Fmt*); | ||
| 198 | extern int runefmtstrinit(Fmt*); | ||
| 199 | extern Rune* runefmtstrflush(Fmt*); | ||
| 200 | |||
| 201 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 202 | extern int dofmt(Fmt*, char*); | ||
| 203 | extern int dorfmt(Fmt*, Rune*); | ||
| 204 | extern int fmtprint(Fmt*, char*, ...); | ||
| 205 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 206 | extern int fmtrune(Fmt*, int); | ||
| 207 | extern int fmtstrcpy(Fmt*, char*); | ||
| 208 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 209 | /* | ||
| 210 | * error string for %r | ||
| 211 | * supplied on per os basis, not part of fmt library | ||
| 212 | */ | ||
| 213 | extern int errfmt(Fmt *f); | ||
| 214 | |||
| 215 | /* | ||
| 216 | * quoted strings | ||
| 217 | */ | ||
| 218 | extern char *unquotestrdup(char*); | ||
| 219 | extern Rune *unquoterunestrdup(Rune*); | ||
| 220 | extern char *quotestrdup(char*); | ||
| 221 | extern Rune *quoterunestrdup(Rune*); | ||
| 222 | extern int quotestrfmt(Fmt*); | ||
| 223 | extern int quoterunestrfmt(Fmt*); | ||
| 224 | extern void quotefmtinstall(void); | ||
| 225 | extern int (*doquote)(int); | ||
| 226 | |||
| 227 | /* | ||
| 228 | * random number | ||
| 229 | */ | ||
| 230 | extern ulong truerand(void); | ||
| 231 | extern ulong ntruerand(ulong); | ||
| 232 | |||
| 233 | /* | ||
| 234 | * math | ||
| 235 | */ | ||
| 236 | extern int isNaN(double); | ||
| 237 | extern int isInf(double, int); | ||
| 238 | |||
| 239 | /* | ||
| 240 | * Time-of-day | ||
| 241 | */ | ||
| 242 | |||
| 243 | typedef struct Tm Tm; | ||
| 244 | struct Tm { | ||
| 245 | int sec; | ||
| 246 | int min; | ||
| 247 | int hour; | ||
| 248 | int mday; | ||
| 249 | int mon; | ||
| 250 | int year; | ||
| 251 | int wday; | ||
| 252 | int yday; | ||
| 253 | char zone[4]; | ||
| 254 | int tzoff; | ||
| 255 | }; | ||
| 256 | extern vlong osnsec(void); | ||
| 257 | #define nsec osnsec | ||
| 258 | |||
| 259 | /* | ||
| 260 | * one-of-a-kind | ||
| 261 | */ | ||
| 262 | extern void _assert(char*); | ||
| 263 | extern double charstod(int(*)(void*), void*); | ||
| 264 | extern char* cleanname(char*); | ||
| 265 | extern uintptr getcallerpc(void*); | ||
| 266 | extern int getfields(char*, char**, int, int, char*); | ||
| 267 | extern char* getuser(void); | ||
| 268 | extern char* getwd(char*, int); | ||
| 269 | extern double ipow10(int); | ||
| 270 | #define pow10 infpow10 | ||
| 271 | extern double pow10(int); | ||
| 272 | extern vlong strtoll(const char*, char**, int); | ||
| 273 | #define qsort infqsort | ||
| 274 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 275 | extern uvlong strtoull(const char*, char**, int); | ||
| 276 | extern void sysfatal(char*, ...); | ||
| 277 | extern int dec64(uchar*, int, char*, int); | ||
| 278 | extern int enc64(char*, int, uchar*, int); | ||
| 279 | extern int dec32(uchar*, int, char*, int); | ||
| 280 | extern int enc32(char*, int, uchar*, int); | ||
| 281 | extern int dec16(uchar*, int, char*, int); | ||
| 282 | extern int enc16(char*, int, uchar*, int); | ||
| 283 | extern int encodefmt(Fmt*); | ||
| 284 | |||
| 285 | /* | ||
| 286 | * synchronization | ||
| 287 | */ | ||
| 288 | typedef | ||
| 289 | struct Lock { | ||
| 290 | ulong val; | ||
| 291 | int pid; | ||
| 292 | } Lock; | ||
| 293 | |||
| 294 | extern ulong _tas(ulong*); | ||
| 295 | |||
| 296 | extern void lock(Lock*); | ||
| 297 | extern void unlock(Lock*); | ||
| 298 | extern int canlock(Lock*); | ||
| 299 | |||
| 300 | typedef struct QLock QLock; | ||
| 301 | struct QLock | ||
| 302 | { | ||
| 303 | Lock use; /* to access Qlock structure */ | ||
| 304 | Proc *head; /* next process waiting for object */ | ||
| 305 | Proc *tail; /* last process waiting for object */ | ||
| 306 | int locked; /* flag */ | ||
| 307 | }; | ||
| 308 | |||
| 309 | extern void qlock(QLock*); | ||
| 310 | extern void qunlock(QLock*); | ||
| 311 | extern int canqlock(QLock*); | ||
| 312 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 313 | |||
| 314 | typedef | ||
| 315 | struct RWLock | ||
| 316 | { | ||
| 317 | Lock l; /* Lock modify lock */ | ||
| 318 | QLock x; /* Mutual exclusion lock */ | ||
| 319 | QLock k; /* Lock for waiting writers */ | ||
| 320 | int readers; /* Count of readers in lock */ | ||
| 321 | } RWLock; | ||
| 322 | |||
| 323 | extern int canrlock(RWLock*); | ||
| 324 | extern int canwlock(RWLock*); | ||
| 325 | extern void rlock(RWLock*); | ||
| 326 | extern void runlock(RWLock*); | ||
| 327 | extern void wlock(RWLock*); | ||
| 328 | extern void wunlock(RWLock*); | ||
| 329 | |||
| 330 | /* | ||
| 331 | * network dialing | ||
| 332 | */ | ||
| 333 | #define NETPATHLEN 40 | ||
| 334 | |||
| 335 | /* | ||
| 336 | * system calls | ||
| 337 | * | ||
| 338 | */ | ||
| 339 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 340 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 341 | #define ERRMAX 128 /* max length of error string */ | ||
| 342 | |||
| 343 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 344 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 345 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 346 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 347 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 348 | #define MCACHE 0x0010 /* cache some data */ | ||
| 349 | #define MMASK 0x0017 /* all bits on */ | ||
| 350 | |||
| 351 | #define OREAD 0 /* open for read */ | ||
| 352 | #define OWRITE 1 /* write */ | ||
| 353 | #define ORDWR 2 /* read and write */ | ||
| 354 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 355 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 356 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 357 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 358 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 359 | |||
| 360 | #define AEXIST 0 /* accessible: exists */ | ||
| 361 | #define AEXEC 1 /* execute access */ | ||
| 362 | #define AWRITE 2 /* write access */ | ||
| 363 | #define AREAD 4 /* read access */ | ||
| 364 | |||
| 365 | /* bits in Qid.type */ | ||
| 366 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 367 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 368 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 369 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 370 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 371 | #define QTFILE 0x00 /* plain file */ | ||
| 372 | |||
| 373 | /* bits in Dir.mode */ | ||
| 374 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 375 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 376 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 377 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 378 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 379 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 380 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 381 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 382 | |||
| 383 | typedef | ||
| 384 | struct Qid | ||
| 385 | { | ||
| 386 | uvlong path; | ||
| 387 | ulong vers; | ||
| 388 | uchar type; | ||
| 389 | } Qid; | ||
| 390 | |||
| 391 | typedef | ||
| 392 | struct Dir { | ||
| 393 | /* system-modified data */ | ||
| 394 | ushort type; /* server type */ | ||
| 395 | uint dev; /* server subtype */ | ||
| 396 | /* file data */ | ||
| 397 | Qid qid; /* unique id from server */ | ||
| 398 | ulong mode; /* permissions */ | ||
| 399 | ulong atime; /* last read time */ | ||
| 400 | ulong mtime; /* last write time */ | ||
| 401 | vlong length; /* file length */ | ||
| 402 | char *name; /* last element of path */ | ||
| 403 | char *uid; /* owner name */ | ||
| 404 | char *gid; /* group name */ | ||
| 405 | char *muid; /* last modifier name */ | ||
| 406 | } Dir; | ||
| 407 | |||
| 408 | extern Dir* dirstat(char*); | ||
| 409 | extern Dir* dirfstat(int); | ||
| 410 | extern int dirwstat(char*, Dir*); | ||
| 411 | extern int dirfwstat(int, Dir*); | ||
| 412 | extern long dirread(int, Dir**); | ||
| 413 | extern void nulldir(Dir*); | ||
| 414 | extern long dirreadall(int, Dir**); | ||
| 415 | |||
| 416 | typedef | ||
| 417 | struct Waitmsg | ||
| 418 | { | ||
| 419 | int pid; /* of loved one */ | ||
| 420 | ulong time[3]; /* of loved one & descendants */ | ||
| 421 | char *msg; | ||
| 422 | } Waitmsg; | ||
| 423 | |||
| 424 | extern void _exits(char*); | ||
| 425 | |||
| 426 | extern void exits(char*); | ||
| 427 | extern int create(char*, int, int); | ||
| 428 | extern int errstr(char*, uint); | ||
| 429 | |||
| 430 | extern void perror(const char*); | ||
| 431 | extern long readn(int, void*, long); | ||
| 432 | extern int remove(const char*); | ||
| 433 | extern void rerrstr(char*, uint); | ||
| 434 | extern vlong seek(int, vlong, int); | ||
| 435 | extern int segflush(void*, ulong); | ||
| 436 | extern void werrstr(char*, ...); | ||
| 437 | |||
| 438 | extern char *argv0; | ||
| 439 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 440 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 441 | argc--, argv++) {\ | ||
| 442 | char *_args, *_argt;\ | ||
| 443 | Rune _argc;\ | ||
| 444 | _args = &argv[0][1];\ | ||
| 445 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 446 | argc--; argv++; break;\ | ||
| 447 | }\ | ||
| 448 | _argc = 0;\ | ||
| 449 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 450 | switch(_argc) | ||
| 451 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 452 | #define ARGF() (_argt=_args, _args="",\ | ||
| 453 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 454 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 455 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 456 | |||
| 457 | #define ARGC() _argc | ||
| 458 | |||
| 459 | /* | ||
| 460 | * Extensions for Inferno to basic libc.h | ||
| 461 | */ | ||
| 462 | |||
| 463 | #define setbinmode() | ||
| 464 | |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,34 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc *getup(void); | ||
| 8 | #define up (getup()) | ||
| 9 | |||
| 10 | /* | ||
| 11 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 12 | */ | ||
| 13 | |||
| 14 | // something is at odds between i386/fpu.h and some of the thread headers | ||
| 15 | #define fp_control inffp_control | ||
| 16 | #define fp_control_t inffp_control_t | ||
| 17 | #define fp_status inffp_status | ||
| 18 | #define fp_status_t inffp_status_t | ||
| 19 | |||
| 20 | #include <architecture/i386/fpu.h> | ||
| 21 | |||
| 22 | typedef struct FPU FPU; | ||
| 23 | struct FPU | ||
| 24 | { | ||
| 25 | fp_state_t env; | ||
| 26 | }; | ||
| 27 | |||
| 28 | #undef fp_control | ||
| 29 | #undef fp_control_t | ||
| 30 | #undef fp_status | ||
| 31 | #undef fp_status_t | ||
| 32 | |||
| 33 | typedef sigjmp_buf osjmpbuf; | ||
| 34 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Linux 386 fpu support | ||
| 3 | * Mimic Plan9 floating point support | ||
| 4 | */ | ||
| 5 | |||
| 6 | static void | ||
| 7 | setfcr(ulong fcr) | ||
| 8 | { | ||
| 9 | __asm__( "xorb $0x3f, %%al\n\t" | ||
| 10 | "pushw %%ax\n\t" | ||
| 11 | "fwait\n\t" | ||
| 12 | "fldcw (%%esp)\n\t" | ||
| 13 | "popw %%ax\n\t" | ||
| 14 | : /* no output */ | ||
| 15 | : "al" (fcr) | ||
| 16 | ); | ||
| 17 | } | ||
| 18 | |||
| 19 | static ulong | ||
| 20 | getfcr(void) | ||
| 21 | { | ||
| 22 | ulong fcr = 0; | ||
| 23 | |||
| 24 | __asm__( "pushl %%eax\n\t" | ||
| 25 | "fwait\n\t" | ||
| 26 | "fstcw (%%esp)\n\t" | ||
| 27 | "popl %%eax\n\t" | ||
| 28 | "xorb $0x3f, %%al\n\t" | ||
| 29 | : "=a" (fcr) | ||
| 30 | : "eax" (fcr) | ||
| 31 | ); | ||
| 32 | return fcr; | ||
| 33 | } | ||
| 34 | |||
| 35 | static ulong | ||
| 36 | getfsr(void) | ||
| 37 | { | ||
| 38 | ulong fsr = -1; | ||
| 39 | |||
| 40 | __asm__( "fwait\n\t" | ||
| 41 | "fstsw (%%eax)\n\t" | ||
| 42 | "movl (%%eax), %%eax\n\t" | ||
| 43 | "andl $0xffff, %%eax\n\t" | ||
| 44 | : "=a" (fsr) | ||
| 45 | : "eax" (&fsr) | ||
| 46 | ); | ||
| 47 | return fsr; | ||
| 48 | } | ||
| 49 | |||
| 50 | static void | ||
| 51 | setfsr(ulong fsr) | ||
| 52 | { | ||
| 53 | __asm__("fclex\n\t"); | ||
| 54 | } | ||
| 55 | |||
| 56 | /* FCR */ | ||
| 57 | #define FPINEX (1<<5) | ||
| 58 | #define FPUNFL ((1<<4)|(1<<1)) | ||
| 59 | #define FPOVFL (1<<3) | ||
| 60 | #define FPZDIV (1<<2) | ||
| 61 | #define FPINVAL (1<<0) | ||
| 62 | #define FPRNR (0<<10) | ||
| 63 | #define FPRZ (3<<10) | ||
| 64 | #define FPRPINF (2<<10) | ||
| 65 | #define FPRNINF (1<<10) | ||
| 66 | #define FPRMASK (3<<10) | ||
| 67 | #define FPPEXT (3<<8) | ||
| 68 | #define FPPSGL (0<<8) | ||
| 69 | #define FPPDBL (2<<8) | ||
| 70 | #define FPPMASK (3<<8) | ||
| 71 | /* FSR */ | ||
| 72 | #define FPAINEX FPINEX | ||
| 73 | #define FPAOVFL FPOVFL | ||
| 74 | #define FPAUNFL FPUNFL | ||
| 75 | #define FPAZDIV FPZDIV | ||
| 76 | #define FPAINVAL FPINVAL | ||
| @@ -0,0 +1,487 @@ | |||
| 1 | /* | ||
| 2 | * Based on FreeBSD lib9.h | ||
| 3 | * Copyright © 1998, 1999 Lucent Technologies Inc. All rights reserved. | ||
| 4 | * Revisions Copyright © 1999, 2002 Vita Nuova Limited. All rights reserved. | ||
| 5 | * Revisions Copyright © 2002, 2003 Corpus Callosum Corporation. All rights reserved. | ||
| 6 | */ | ||
| 7 | |||
| 8 | /* define _BSD_SOURCE to use ISO C, POSIX, and 4.4BSD things. */ | ||
| 9 | #ifndef _BSD_SOURCE | ||
| 10 | #define _BSD_SOURCE | ||
| 11 | #endif | ||
| 12 | #define _LARGEFILE64_SOURCE 1 | ||
| 13 | #define _FILE_OFFSET_BITS 64 | ||
| 14 | |||
| 15 | #include <sys/types.h> | ||
| 16 | #include <sys/stat.h> | ||
| 17 | #include <stdlib.h> | ||
| 18 | #include <stdarg.h> | ||
| 19 | #include <unistd.h> | ||
| 20 | #include <errno.h> | ||
| 21 | #include <string.h> | ||
| 22 | // #include "math.h" | ||
| 23 | #include <fcntl.h> | ||
| 24 | #include <setjmp.h> | ||
| 25 | #include <float.h> | ||
| 26 | #include <time.h> | ||
| 27 | |||
| 28 | #define nil ((void*)0) | ||
| 29 | |||
| 30 | // typedef unsigned short ushort; | ||
| 31 | typedef unsigned char uchar; | ||
| 32 | typedef unsigned long ulong; | ||
| 33 | // typedef unsigned int uint; | ||
| 34 | typedef signed char schar; | ||
| 35 | typedef long long vlong; | ||
| 36 | typedef unsigned long long uvlong; | ||
| 37 | typedef ushort Rune; | ||
| 38 | typedef unsigned int u32int; | ||
| 39 | typedef uvlong u64int; | ||
| 40 | |||
| 41 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 42 | typedef unsigned short u16int; | ||
| 43 | typedef unsigned char u8int; | ||
| 44 | typedef unsigned long uintptr; | ||
| 45 | |||
| 46 | typedef signed char int8; | ||
| 47 | typedef unsigned char uint8; | ||
| 48 | typedef short int16; | ||
| 49 | typedef unsigned short uint16; | ||
| 50 | typedef int int32; | ||
| 51 | typedef unsigned int uint32; | ||
| 52 | typedef long long int64; | ||
| 53 | typedef unsigned long long uint64; | ||
| 54 | |||
| 55 | /* handle conflicts with host os libs */ | ||
| 56 | #define getwd infgetwd | ||
| 57 | #define scalb infscalb | ||
| 58 | #define div infdiv | ||
| 59 | #define panic infpanic | ||
| 60 | #define rint infrint | ||
| 61 | #define rcmd infrcmd | ||
| 62 | #define pow10 infpow10 | ||
| 63 | |||
| 64 | #ifndef EMU | ||
| 65 | typedef struct Proc Proc; | ||
| 66 | #endif | ||
| 67 | |||
| 68 | /* | ||
| 69 | * math module dtoa | ||
| 70 | */ | ||
| 71 | #include <machine/endian.h> | ||
| 72 | #define __LITTLE_ENDIAN | ||
| 73 | |||
| 74 | #define USED(x) if(x){}else{} | ||
| 75 | #define SET(x) | ||
| 76 | |||
| 77 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 78 | #undef offsetof | ||
| 79 | #undef assert | ||
| 80 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 81 | #define assert(x) if(x){}else _assert("x") | ||
| 82 | |||
| 83 | /* | ||
| 84 | * mem and string routines are declared by ANSI/POSIX files above | ||
| 85 | */ | ||
| 86 | |||
| 87 | extern char* strecpy(char*, char*, char*); | ||
| 88 | extern char* strdup(const char*); | ||
| 89 | extern int cistrncmp(char*, char*, int); | ||
| 90 | extern int cistrcmp(char*, char*); | ||
| 91 | extern char* cistrstr(char*, char*); | ||
| 92 | extern int tokenize(char*, char**, int); | ||
| 93 | extern vlong strtoll(const char*, char**, int); | ||
| 94 | #define qsort infqsort | ||
| 95 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 96 | |||
| 97 | enum | ||
| 98 | { | ||
| 99 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 100 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 101 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 102 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 103 | }; | ||
| 104 | |||
| 105 | /* | ||
| 106 | * rune routines | ||
| 107 | */ | ||
| 108 | extern int runetochar(char*, Rune*); | ||
| 109 | extern int chartorune(Rune*, char*); | ||
| 110 | extern int runelen(long); | ||
| 111 | extern int runenlen(Rune*, int); | ||
| 112 | extern int fullrune(char*, int); | ||
| 113 | extern int utflen(char*); | ||
| 114 | extern int utfnlen(char*, long); | ||
| 115 | extern char* utfrune(char*, long); | ||
| 116 | extern char* utfrrune(char*, long); | ||
| 117 | extern char* utfutf(char*, char*); | ||
| 118 | extern char* utfecpy(char*, char*, char*); | ||
| 119 | |||
| 120 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 121 | extern Rune* runestrchr(Rune*, Rune); | ||
| 122 | extern int runestrcmp(Rune*, Rune*); | ||
| 123 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 124 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 125 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 126 | extern Rune* runestrdup(Rune*); | ||
| 127 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 128 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 129 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 130 | extern long runestrlen(Rune*); | ||
| 131 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 132 | |||
| 133 | extern Rune tolowerrune(Rune); | ||
| 134 | extern Rune totitlerune(Rune); | ||
| 135 | extern Rune toupperrune(Rune); | ||
| 136 | extern int isalpharune(Rune); | ||
| 137 | extern int islowerrune(Rune); | ||
| 138 | extern int isspacerune(Rune); | ||
| 139 | extern int istitlerune(Rune); | ||
| 140 | extern int isupperrune(Rune); | ||
| 141 | |||
| 142 | /* | ||
| 143 | * malloc | ||
| 144 | */ | ||
| 145 | extern void* malloc(size_t); | ||
| 146 | extern void* mallocz(ulong, int); | ||
| 147 | extern void free(void*); | ||
| 148 | extern ulong msize(void*); | ||
| 149 | extern void* calloc(size_t, size_t); | ||
| 150 | extern void* realloc(void*, size_t); | ||
| 151 | extern void setmalloctag(void*, ulong); | ||
| 152 | extern void setrealloctag(void*, ulong); | ||
| 153 | extern ulong getmalloctag(void*); | ||
| 154 | extern ulong getrealloctag(void*); | ||
| 155 | extern void* malloctopoolblock(void*); | ||
| 156 | |||
| 157 | /* | ||
| 158 | * print routines | ||
| 159 | */ | ||
| 160 | typedef struct Fmt Fmt; | ||
| 161 | struct Fmt{ | ||
| 162 | uchar runes; /* output buffer is runes or chars? */ | ||
| 163 | void *start; /* of buffer */ | ||
| 164 | void *to; /* current place in the buffer */ | ||
| 165 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 166 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 167 | void *farg; /* to make flush a closure */ | ||
| 168 | int nfmt; /* num chars formatted so far */ | ||
| 169 | va_list args; /* args passed to dofmt */ | ||
| 170 | int r; /* % format Rune */ | ||
| 171 | int width; | ||
| 172 | int prec; | ||
| 173 | ulong flags; | ||
| 174 | }; | ||
| 175 | |||
| 176 | enum{ | ||
| 177 | FmtWidth = 1, | ||
| 178 | FmtLeft = FmtWidth << 1, | ||
| 179 | FmtPrec = FmtLeft << 1, | ||
| 180 | FmtSharp = FmtPrec << 1, | ||
| 181 | FmtSpace = FmtSharp << 1, | ||
| 182 | FmtSign = FmtSpace << 1, | ||
| 183 | FmtZero = FmtSign << 1, | ||
| 184 | FmtUnsigned = FmtZero << 1, | ||
| 185 | FmtShort = FmtUnsigned << 1, | ||
| 186 | FmtLong = FmtShort << 1, | ||
| 187 | FmtVLong = FmtLong << 1, | ||
| 188 | FmtComma = FmtVLong << 1, | ||
| 189 | FmtByte = FmtComma << 1, | ||
| 190 | |||
| 191 | FmtFlag = FmtByte << 1 | ||
| 192 | }; | ||
| 193 | |||
| 194 | extern int print(char*, ...); | ||
| 195 | extern char* seprint(char*, char*, char*, ...); | ||
| 196 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 197 | extern int snprint(char*, int, char*, ...); | ||
| 198 | extern int vsnprint(char*, int, char*, va_list); | ||
| 199 | extern char* smprint(char*, ...); | ||
| 200 | extern char* vsmprint(char*, va_list); | ||
| 201 | extern int sprint(char*, char*, ...); | ||
| 202 | extern int fprint(int, char*, ...); | ||
| 203 | extern int vfprint(int, char*, va_list); | ||
| 204 | |||
| 205 | extern int runesprint(Rune*, char*, ...); | ||
| 206 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 207 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 208 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 209 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 210 | extern Rune* runesmprint(char*, ...); | ||
| 211 | extern Rune* runevsmprint(char*, va_list); | ||
| 212 | |||
| 213 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 214 | extern int fmtfdflush(Fmt*); | ||
| 215 | extern int fmtstrinit(Fmt*); | ||
| 216 | extern char* fmtstrflush(Fmt*); | ||
| 217 | extern int runefmtstrinit(Fmt*); | ||
| 218 | extern Rune* runefmtstrflush(Fmt*); | ||
| 219 | |||
| 220 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 221 | extern int dofmt(Fmt*, char*); | ||
| 222 | extern int dorfmt(Fmt*, Rune*); | ||
| 223 | extern int fmtprint(Fmt*, char*, ...); | ||
| 224 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 225 | extern int fmtrune(Fmt*, int); | ||
| 226 | extern int fmtstrcpy(Fmt*, char*); | ||
| 227 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 228 | /* | ||
| 229 | * error string for %r | ||
| 230 | * supplied on per os basis, not part of fmt library | ||
| 231 | */ | ||
| 232 | extern int errfmt(Fmt *f); | ||
| 233 | |||
| 234 | /* | ||
| 235 | * quoted strings | ||
| 236 | */ | ||
| 237 | extern char *unquotestrdup(char*); | ||
| 238 | extern Rune *unquoterunestrdup(Rune*); | ||
| 239 | extern char *quotestrdup(char*); | ||
| 240 | extern Rune *quoterunestrdup(Rune*); | ||
| 241 | extern int quotestrfmt(Fmt*); | ||
| 242 | extern int quoterunestrfmt(Fmt*); | ||
| 243 | extern void quotefmtinstall(void); | ||
| 244 | extern int (*doquote)(int); | ||
| 245 | |||
| 246 | /* | ||
| 247 | * random number | ||
| 248 | */ | ||
| 249 | |||
| 250 | extern int nrand(int); | ||
| 251 | extern ulong truerand(void); | ||
| 252 | extern ulong ntruerand(ulong); | ||
| 253 | |||
| 254 | /* | ||
| 255 | * math | ||
| 256 | */ | ||
| 257 | extern int isNaN(double); | ||
| 258 | extern int isInf(double, int); | ||
| 259 | extern double pow(double, double); | ||
| 260 | |||
| 261 | /* | ||
| 262 | * Time-of-day | ||
| 263 | */ | ||
| 264 | |||
| 265 | typedef struct Tm Tm; | ||
| 266 | struct Tm { | ||
| 267 | int sec; | ||
| 268 | int min; | ||
| 269 | int hour; | ||
| 270 | int mday; | ||
| 271 | int mon; | ||
| 272 | int year; | ||
| 273 | int wday; | ||
| 274 | int yday; | ||
| 275 | char zone[4]; | ||
| 276 | int tzoff; | ||
| 277 | }; | ||
| 278 | extern vlong osnsec(void); | ||
| 279 | #define nsec osnsec | ||
| 280 | |||
| 281 | /* | ||
| 282 | * one-of-a-kind | ||
| 283 | */ | ||
| 284 | extern void _assert(char*); | ||
| 285 | extern double charstod(int(*)(void*), void*); | ||
| 286 | extern char* cleanname(char*); | ||
| 287 | extern double frexp(double, int*); | ||
| 288 | extern uintptr getcallerpc(void*); | ||
| 289 | extern int getfields(char*, char**, int, int, char*); | ||
| 290 | extern char* getuser(void); | ||
| 291 | extern char* getwd(char*, int); | ||
| 292 | extern double ipow10(int); | ||
| 293 | extern double ldexp(double, int); | ||
| 294 | extern double modf(double, double*); | ||
| 295 | extern void perror(const char*); | ||
| 296 | extern double pow10(int); | ||
| 297 | extern uvlong strtoull(const char*, char**, int); | ||
| 298 | extern void sysfatal(char*, ...); | ||
| 299 | extern int dec64(uchar*, int, char*, int); | ||
| 300 | extern int enc64(char*, int, uchar*, int); | ||
| 301 | extern int dec32(uchar*, int, char*, int); | ||
| 302 | extern int enc32(char*, int, uchar*, int); | ||
| 303 | extern int dec16(uchar*, int, char*, int); | ||
| 304 | extern int enc16(char*, int, uchar*, int); | ||
| 305 | extern int encodefmt(Fmt*); | ||
| 306 | |||
| 307 | /* | ||
| 308 | * synchronization | ||
| 309 | */ | ||
| 310 | typedef | ||
| 311 | struct Lock { | ||
| 312 | int val; | ||
| 313 | int pid; | ||
| 314 | } Lock; | ||
| 315 | |||
| 316 | extern int _tas(int*); | ||
| 317 | |||
| 318 | extern void lock(Lock*); | ||
| 319 | extern void unlock(Lock*); | ||
| 320 | extern int canlock(Lock*); | ||
| 321 | |||
| 322 | typedef struct QLock QLock; | ||
| 323 | struct QLock | ||
| 324 | { | ||
| 325 | Lock use; /* to access Qlock structure */ | ||
| 326 | Proc *head; /* next process waiting for object */ | ||
| 327 | Proc *tail; /* last process waiting for object */ | ||
| 328 | int locked; /* flag */ | ||
| 329 | }; | ||
| 330 | |||
| 331 | extern void qlock(QLock*); | ||
| 332 | extern void qunlock(QLock*); | ||
| 333 | extern int canqlock(QLock*); | ||
| 334 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 335 | |||
| 336 | typedef | ||
| 337 | struct RWLock | ||
| 338 | { | ||
| 339 | Lock l; /* Lock modify lock */ | ||
| 340 | QLock x; /* Mutual exclusion lock */ | ||
| 341 | QLock k; /* Lock for waiting writers */ | ||
| 342 | int readers; /* Count of readers in lock */ | ||
| 343 | } RWLock; | ||
| 344 | |||
| 345 | extern int canrlock(RWLock*); | ||
| 346 | extern int canwlock(RWLock*); | ||
| 347 | extern void rlock(RWLock*); | ||
| 348 | extern void runlock(RWLock*); | ||
| 349 | extern void wlock(RWLock*); | ||
| 350 | extern void wunlock(RWLock*); | ||
| 351 | |||
| 352 | /* | ||
| 353 | * network dialing | ||
| 354 | */ | ||
| 355 | #define NETPATHLEN 40 | ||
| 356 | |||
| 357 | /* | ||
| 358 | * system calls | ||
| 359 | * | ||
| 360 | */ | ||
| 361 | |||
| 362 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 363 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 364 | #define ERRMAX 128 /* max length of error string */ | ||
| 365 | |||
| 366 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 367 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 368 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 369 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 370 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 371 | #define MCACHE 0x0010 /* cache some data */ | ||
| 372 | #define MMASK 0x0017 /* all bits on */ | ||
| 373 | |||
| 374 | #define OREAD 0 /* open for read */ | ||
| 375 | #define OWRITE 1 /* write */ | ||
| 376 | #define ORDWR 2 /* read and write */ | ||
| 377 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 378 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 379 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 380 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 381 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 382 | |||
| 383 | #define AEXIST 0 /* accessible: exists */ | ||
| 384 | #define AEXEC 1 /* execute access */ | ||
| 385 | #define AWRITE 2 /* write access */ | ||
| 386 | #define AREAD 4 /* read access */ | ||
| 387 | |||
| 388 | /* bits in Qid.type */ | ||
| 389 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 390 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 391 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 392 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 393 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 394 | #define QTFILE 0x00 /* plain file */ | ||
| 395 | |||
| 396 | /* bits in Dir.mode */ | ||
| 397 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 398 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 399 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 400 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 401 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 402 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 403 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 404 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 405 | |||
| 406 | typedef | ||
| 407 | struct Qid | ||
| 408 | { | ||
| 409 | uvlong path; | ||
| 410 | ulong vers; | ||
| 411 | uchar type; | ||
| 412 | } Qid; | ||
| 413 | |||
| 414 | typedef | ||
| 415 | struct Dir { | ||
| 416 | /* system-modified data */ | ||
| 417 | ushort type; /* server type */ | ||
| 418 | uint dev; /* server subtype */ | ||
| 419 | /* file data */ | ||
| 420 | Qid qid; /* unique id from server */ | ||
| 421 | ulong mode; /* permissions */ | ||
| 422 | ulong atime; /* last read time */ | ||
| 423 | ulong mtime; /* last write time */ | ||
| 424 | vlong length; /* file length */ | ||
| 425 | char *name; /* last element of path */ | ||
| 426 | char *uid; /* owner name */ | ||
| 427 | char *gid; /* group name */ | ||
| 428 | char *muid; /* last modifier name */ | ||
| 429 | } Dir; | ||
| 430 | |||
| 431 | extern Dir* dirstat(char*); | ||
| 432 | extern Dir* dirfstat(int); | ||
| 433 | extern int dirwstat(char*, Dir*); | ||
| 434 | extern int dirfwstat(int, Dir*); | ||
| 435 | extern long dirread(int, Dir**); | ||
| 436 | extern void nulldir(Dir*); | ||
| 437 | extern long dirreadall(int, Dir**); | ||
| 438 | |||
| 439 | typedef | ||
| 440 | struct Waitmsg | ||
| 441 | { | ||
| 442 | int pid; /* of loved one */ | ||
| 443 | ulong time[3]; /* of loved one & descendants */ | ||
| 444 | char *msg; | ||
| 445 | } Waitmsg; | ||
| 446 | |||
| 447 | extern void _exits(char*); | ||
| 448 | |||
| 449 | extern void exits(char*); | ||
| 450 | extern int create(char*, int, int); | ||
| 451 | extern int errstr(char*, uint); | ||
| 452 | |||
| 453 | extern void perror(const char*); | ||
| 454 | extern long readn(int, void*, long); | ||
| 455 | extern int remove(const char*); | ||
| 456 | extern void rerrstr(char*, uint); | ||
| 457 | extern vlong seek(int, vlong, int); | ||
| 458 | extern int segflush(void*, ulong); | ||
| 459 | extern void werrstr(char*, ...); | ||
| 460 | |||
| 461 | extern char *argv0; | ||
| 462 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 463 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 464 | argc--, argv++) {\ | ||
| 465 | char *_args, *_argt;\ | ||
| 466 | Rune _argc;\ | ||
| 467 | _args = &argv[0][1];\ | ||
| 468 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 469 | argc--; argv++; break;\ | ||
| 470 | }\ | ||
| 471 | _argc = 0;\ | ||
| 472 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 473 | switch(_argc) | ||
| 474 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 475 | #define ARGF() (_argt=_args, _args="",\ | ||
| 476 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 477 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 478 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 479 | |||
| 480 | #define ARGC() _argc | ||
| 481 | |||
| 482 | /* | ||
| 483 | * Extensions for Inferno to basic libc.h | ||
| 484 | */ | ||
| 485 | |||
| 486 | #define setbinmode() | ||
| 487 | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | This file is of historical interest only, but serves to note that | ||
| 2 | much of the work of the MacOSX ports was originally done by Corpus Callosum. | ||
| 3 | Bugs to support@vitanuova.com, though. | ||
| 4 | |||
| 5 | March 2006: initial MacOSX 10.4/x86 port | ||
| 6 | |||
| 7 | 12-Dec-2003 | ||
| 8 | Emu can use wm with Apple's X11R6 again. | ||
| 9 | |||
| 10 | 08-Dec-2003 | ||
| 11 | Inferno Services (6660, 6666-6676, 2202) | ||
| 12 | |||
| 13 | 26-Aug-2003 | ||
| 14 | In order to run and use Inferno services appropriately on OSX, you need to ensure that the Sharing System Preferences include an entry in the Firewall section that is turned on and looks like the following line: | ||
| 15 | |||
| 16 | Inferno services (6660, 6666-6674) | ||
| 17 | |||
| 18 | |||
| 19 | 05-Jul-2003 | ||
| 20 | In order to support 1.4, the build will now use the default 'mk' provided with the Inferno distribution. You can also copy tcshrc to the Inferno ROOT and source the file from that directory before running or building emu. Modified mkfiles and sources are now available in the srcMacOSX archive. You may also want to change 'mkconfig' with the following diff | ||
| 21 | |||
| 22 | % cvs diff -r 1.1 mkconfig | ||
| 23 | Index: mkconfig | ||
| 24 | =================================================================== | ||
| 25 | RCS file: /usr/local/Repository/cvs/vitanuova/inferno_v14/mkconfig,v | ||
| 26 | retrieving revision 1.1 | ||
| 27 | retrieving revision 1.3 | ||
| 28 | diff -r1.1 -r1.3 | ||
| 29 | 7c7 | ||
| 30 | < ROOT=/usr/inferno | ||
| 31 | --- | ||
| 32 | > ROOT=$ROOT | ||
| 33 | 17c17 | ||
| 34 | < SYSHOST=Plan9 # build system OS type (Hp, Inferno, Irix, Linux, Nt, Plan9, Solaris) | ||
| 35 | --- | ||
| 36 | > SYSHOST=MacOSX # build system OS type (Hp, Inferno, Irix, Linux, Nt, Plan9, Solaris) | ||
| 37 | 25c25 | ||
| 38 | < OBJTYPE=$objtype | ||
| 39 | --- | ||
| 40 | > OBJTYPE=power | ||
| 41 | |||
| 42 | |||
| 43 | |||
| 44 | 16-May-2003 | ||
| 45 | |||
| 46 | The build now uses the open sourced 'mk' from http://www.pdos.lcs.mit.edu/~rsc/software/ | ||
| 47 | |||
| 48 | There is a file .tcshrc at the root of this tree (..) that can be used to set up the environment required to build emu. | ||
| 49 | |||
| 50 | |||
| 51 | |||
| 52 | 28-Feb-2001 | ||
| 53 | |||
| 54 | The initial port has been provided by Corpus Callosum Corporation. | ||
| 55 | |||
| 56 | This port of Inferno for Darwin, Mac OS X, and Mac OS X Server hosted environments currently provides base 'emu' support. Wm, audio, and other services are not currently ported. It has only been tested on UFS partitions and will require further testing for HFS+ support. | ||
| 57 | |||
| 58 | Emu -c1 currently errors out as "Illegal instruction" | ||
| 59 | |||
| 60 | Various malloc/free (from libc/System on Mac OS X/Darwin) warnings should be removed in the following version. | ||
| 61 | |||
| 62 | eia devices will recognize /dev/ttyd.irda and /dev/ttyd.modem though both are completely untested (need to get updates to the RCX interface to test irda). | ||
| 63 | |||
| 64 | The following modification was added to various 'mkfile' to support required redefinition of varios core functions. | ||
| 65 | |||
| 66 | <$ROOT/mkfiles/mkalloc-$SYSHOST-$OBJTYPE | ||
| 67 | |||
| 68 | Some of the base libraries and utils will have *.pbproj files which were used to bootstrap the initial build system on Mac OS X (Public Beta). | ||
| 69 | |||
| 70 | |||
| 71 | |||
| 72 | "Mac OS X" and "Mac OS X Server" are trade marks of Apple Computer, Inc. | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,22 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc *getup(void); | ||
| 8 | #define up (getup()) | ||
| 9 | |||
| 10 | /* | ||
| 11 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <architecture/ppc/fp_regs.h> | ||
| 15 | |||
| 16 | typedef union { | ||
| 17 | double __dbl; | ||
| 18 | ppc_fp_scr_t __src; | ||
| 19 | } FPU; | ||
| 20 | |||
| 21 | typedef sigjmp_buf osjmpbuf; | ||
| 22 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| @@ -0,0 +1,81 @@ | |||
| 1 | /* | ||
| 2 | * MacOSX/Darwin ppc fpu support | ||
| 3 | * Mimic Plan9 floating point support | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <architecture/ppc/fp_regs.h> | ||
| 7 | |||
| 8 | static __inline__ ulong | ||
| 9 | getfcr(void) | ||
| 10 | { | ||
| 11 | ppc_fp_scr_t fpscr = get_fp_scr(); | ||
| 12 | return ((ulong *)&fpscr)[1]; | ||
| 13 | } | ||
| 14 | |||
| 15 | ulong | ||
| 16 | getfsr(void) | ||
| 17 | { | ||
| 18 | ppc_fp_scr_t fpscr = get_fp_scr(); | ||
| 19 | return ((ulong *)&fpscr)[1]; | ||
| 20 | } | ||
| 21 | |||
| 22 | void | ||
| 23 | setfsr(ulong fsr) | ||
| 24 | { | ||
| 25 | ppc_fp_scr_t fpscr; | ||
| 26 | // fpscr = get_fp_scr(); | ||
| 27 | (((ulong *)&fpscr)[1]) = fsr; | ||
| 28 | set_fp_scr(fpscr); | ||
| 29 | } | ||
| 30 | |||
| 31 | void | ||
| 32 | setfcr(ulong fcr) | ||
| 33 | { | ||
| 34 | ppc_fp_scr_t fpscr; | ||
| 35 | // fpscr = get_fp_scr(); | ||
| 36 | (((ulong *)&fpscr)[1]) = fcr; | ||
| 37 | set_fp_scr(fpscr); | ||
| 38 | } | ||
| 39 | |||
| 40 | /* FPSCR */ | ||
| 41 | #define FPSFX (1<<31) /* exception summary (sticky) */ | ||
| 42 | #define FPSEX (1<<30) /* enabled exception summary */ | ||
| 43 | #define FPSVX (1<<29) /* invalid operation exception summary */ | ||
| 44 | #define FPSOX (1<<28) /* overflow exception OX (sticky) */ | ||
| 45 | #define FPSUX (1<<27) /* underflow exception UX (sticky) */ | ||
| 46 | #define FPSZX (1<<26) /* zero divide exception ZX (sticky) */ | ||
| 47 | #define FPSXX (1<<25) /* inexact exception XX (sticky) */ | ||
| 48 | #define FPSVXSNAN (1<<24) /* invalid operation exception for SNaN (sticky) */ | ||
| 49 | #define FPSVXISI (1<<23) /* invalid operation exception for ∞-∞ (sticky) */ | ||
| 50 | #define FPSVXIDI (1<<22) /* invalid operation exception for ∞/∞ (sticky) */ | ||
| 51 | #define FPSVXZDZ (1<<21) /* invalid operation exception for 0/0 (sticky) */ | ||
| 52 | #define FPSVXIMZ (1<<20) /* invalid operation exception for ∞*0 (sticky) */ | ||
| 53 | #define FPSVXVC (1<<19) /* invalid operation exception for invalid compare (sticky) */ | ||
| 54 | #define FPSFR (1<<18) /* fraction rounded */ | ||
| 55 | #define FPSFI (1<<17) /* fraction inexact */ | ||
| 56 | #define FPSFPRF (1<<16) /* floating point result class */ | ||
| 57 | #define FPSFPCC (0xF<<12) /* <, >, =, unordered */ | ||
| 58 | #define FPVXCVI (1<<8) /* enable exception for invalid integer convert (sticky) */ | ||
| 59 | |||
| 60 | /* FCR */ | ||
| 61 | #define FPVE (1<<7) /* invalid operation exception enable */ | ||
| 62 | #define FPOVFL (1<<6) /* enable overflow exceptions */ | ||
| 63 | #define FPUNFL (1<<5) /* enable underflow */ | ||
| 64 | #define FPZDIV (1<<4) /* enable zero divide */ | ||
| 65 | #define FPINEX (1<<3) /* enable inexact exceptions */ | ||
| 66 | #define FPRMASK (3<<0) /* rounding mode */ | ||
| 67 | #define FPRNR (0<<0) | ||
| 68 | #define FPRZ (1<<0) | ||
| 69 | #define FPRPINF (2<<0) | ||
| 70 | #define FPRNINF (3<<0) | ||
| 71 | #define FPPEXT 0 | ||
| 72 | #define FPPSGL 0 | ||
| 73 | #define FPPDBL 0 | ||
| 74 | #define FPPMASK 0 | ||
| 75 | #define FPINVAL FPVE | ||
| 76 | /* FSR */ | ||
| 77 | #define FPAOVFL FPSOX | ||
| 78 | #define FPAINEX FPSXX | ||
| 79 | #define FPAUNFL FPSUX | ||
| 80 | #define FPAZDIV FPSZX | ||
| 81 | #define FPAINVAL FPSVX | ||
| @@ -0,0 +1,487 @@ | |||
| 1 | /* | ||
| 2 | * Based on FreeBSD lib9.h | ||
| 3 | * Copyright © 1998, 1999 Lucent Technologies Inc. All rights reserved. | ||
| 4 | * Revisions Copyright © 1999, 2002 Vita Nuova Limited. All rights reserved. | ||
| 5 | * Revisions Copyright © 2002, 2003 Corpus Callosum Corporation. All rights reserved. | ||
| 6 | */ | ||
| 7 | |||
| 8 | /* define _BSD_SOURCE to use ISO C, POSIX, and 4.4BSD things. */ | ||
| 9 | #ifndef _BSD_SOURCE | ||
| 10 | #define _BSD_SOURCE | ||
| 11 | #endif | ||
| 12 | #define _LARGEFILE64_SOURCE 1 | ||
| 13 | #define _FILE_OFFSET_BITS 64 | ||
| 14 | |||
| 15 | #include <sys/types.h> | ||
| 16 | #include <sys/stat.h> | ||
| 17 | #include <stdlib.h> | ||
| 18 | #include <stdarg.h> | ||
| 19 | #include <unistd.h> | ||
| 20 | #include <errno.h> | ||
| 21 | #include <string.h> | ||
| 22 | // #include "math.h" | ||
| 23 | #include <fcntl.h> | ||
| 24 | #include <setjmp.h> | ||
| 25 | #include <float.h> | ||
| 26 | #include <time.h> | ||
| 27 | |||
| 28 | #define nil ((void*)0) | ||
| 29 | |||
| 30 | // typedef unsigned short ushort; | ||
| 31 | typedef unsigned char uchar; | ||
| 32 | typedef unsigned long ulong; | ||
| 33 | // typedef unsigned int uint; | ||
| 34 | typedef signed char schar; | ||
| 35 | typedef long long vlong; | ||
| 36 | typedef unsigned long long uvlong; | ||
| 37 | typedef ushort Rune; | ||
| 38 | typedef unsigned int u32int; | ||
| 39 | typedef uvlong u64int; | ||
| 40 | |||
| 41 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 42 | typedef unsigned short u16int; | ||
| 43 | typedef unsigned char u8int; | ||
| 44 | typedef unsigned long uintptr; | ||
| 45 | |||
| 46 | typedef signed char int8; | ||
| 47 | typedef unsigned char uint8; | ||
| 48 | typedef short int16; | ||
| 49 | typedef unsigned short uint16; | ||
| 50 | typedef int int32; | ||
| 51 | typedef unsigned int uint32; | ||
| 52 | typedef long long int64; | ||
| 53 | typedef unsigned long long uint64; | ||
| 54 | |||
| 55 | /* handle conflicts with host os libs */ | ||
| 56 | #define getwd infgetwd | ||
| 57 | #define scalb infscalb | ||
| 58 | #define div infdiv | ||
| 59 | #define panic infpanic | ||
| 60 | #define rint infrint | ||
| 61 | #define rcmd infrcmd | ||
| 62 | #define pow10 infpow10 | ||
| 63 | |||
| 64 | #ifndef EMU | ||
| 65 | typedef struct Proc Proc; | ||
| 66 | #endif | ||
| 67 | |||
| 68 | /* | ||
| 69 | * math module dtoa | ||
| 70 | */ | ||
| 71 | #include <machine/endian.h> | ||
| 72 | #define __BIG_ENDIAN | ||
| 73 | |||
| 74 | #define USED(x) if(x){}else{} | ||
| 75 | #define SET(x) | ||
| 76 | |||
| 77 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 78 | #undef offsetof | ||
| 79 | #undef assert | ||
| 80 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 81 | #define assert(x) if(x){}else _assert("x") | ||
| 82 | |||
| 83 | /* | ||
| 84 | * mem and string routines are declared by ANSI/POSIX files above | ||
| 85 | */ | ||
| 86 | |||
| 87 | extern char* strecpy(char*, char*, char*); | ||
| 88 | extern char* strdup(const char*); | ||
| 89 | extern int cistrncmp(char*, char*, int); | ||
| 90 | extern int cistrcmp(char*, char*); | ||
| 91 | extern char* cistrstr(char*, char*); | ||
| 92 | extern int tokenize(char*, char**, int); | ||
| 93 | extern vlong strtoll(const char*, char**, int); | ||
| 94 | #define qsort infqsort | ||
| 95 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 96 | |||
| 97 | enum | ||
| 98 | { | ||
| 99 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 100 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 101 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 102 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 103 | }; | ||
| 104 | |||
| 105 | /* | ||
| 106 | * rune routines | ||
| 107 | */ | ||
| 108 | extern int runetochar(char*, Rune*); | ||
| 109 | extern int chartorune(Rune*, char*); | ||
| 110 | extern int runelen(long); | ||
| 111 | extern int runenlen(Rune*, int); | ||
| 112 | extern int fullrune(char*, int); | ||
| 113 | extern int utflen(char*); | ||
| 114 | extern int utfnlen(char*, long); | ||
| 115 | extern char* utfrune(char*, long); | ||
| 116 | extern char* utfrrune(char*, long); | ||
| 117 | extern char* utfutf(char*, char*); | ||
| 118 | extern char* utfecpy(char*, char*, char*); | ||
| 119 | |||
| 120 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 121 | extern Rune* runestrchr(Rune*, Rune); | ||
| 122 | extern int runestrcmp(Rune*, Rune*); | ||
| 123 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 124 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 125 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 126 | extern Rune* runestrdup(Rune*); | ||
| 127 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 128 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 129 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 130 | extern long runestrlen(Rune*); | ||
| 131 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 132 | |||
| 133 | extern Rune tolowerrune(Rune); | ||
| 134 | extern Rune totitlerune(Rune); | ||
| 135 | extern Rune toupperrune(Rune); | ||
| 136 | extern int isalpharune(Rune); | ||
| 137 | extern int islowerrune(Rune); | ||
| 138 | extern int isspacerune(Rune); | ||
| 139 | extern int istitlerune(Rune); | ||
| 140 | extern int isupperrune(Rune); | ||
| 141 | |||
| 142 | /* | ||
| 143 | * malloc | ||
| 144 | */ | ||
| 145 | extern void* malloc(size_t); | ||
| 146 | extern void* mallocz(ulong, int); | ||
| 147 | extern void free(void*); | ||
| 148 | extern ulong msize(void*); | ||
| 149 | extern void* calloc(size_t, size_t); | ||
| 150 | extern void* realloc(void*, size_t); | ||
| 151 | extern void setmalloctag(void*, ulong); | ||
| 152 | extern void setrealloctag(void*, ulong); | ||
| 153 | extern ulong getmalloctag(void*); | ||
| 154 | extern ulong getrealloctag(void*); | ||
| 155 | extern void* malloctopoolblock(void*); | ||
| 156 | |||
| 157 | /* | ||
| 158 | * print routines | ||
| 159 | */ | ||
| 160 | typedef struct Fmt Fmt; | ||
| 161 | struct Fmt{ | ||
| 162 | uchar runes; /* output buffer is runes or chars? */ | ||
| 163 | void *start; /* of buffer */ | ||
| 164 | void *to; /* current place in the buffer */ | ||
| 165 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 166 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 167 | void *farg; /* to make flush a closure */ | ||
| 168 | int nfmt; /* num chars formatted so far */ | ||
| 169 | va_list args; /* args passed to dofmt */ | ||
| 170 | int r; /* % format Rune */ | ||
| 171 | int width; | ||
| 172 | int prec; | ||
| 173 | ulong flags; | ||
| 174 | }; | ||
| 175 | |||
| 176 | enum{ | ||
| 177 | FmtWidth = 1, | ||
| 178 | FmtLeft = FmtWidth << 1, | ||
| 179 | FmtPrec = FmtLeft << 1, | ||
| 180 | FmtSharp = FmtPrec << 1, | ||
| 181 | FmtSpace = FmtSharp << 1, | ||
| 182 | FmtSign = FmtSpace << 1, | ||
| 183 | FmtZero = FmtSign << 1, | ||
| 184 | FmtUnsigned = FmtZero << 1, | ||
| 185 | FmtShort = FmtUnsigned << 1, | ||
| 186 | FmtLong = FmtShort << 1, | ||
| 187 | FmtVLong = FmtLong << 1, | ||
| 188 | FmtComma = FmtVLong << 1, | ||
| 189 | FmtByte = FmtComma << 1, | ||
| 190 | |||
| 191 | FmtFlag = FmtByte << 1 | ||
| 192 | }; | ||
| 193 | |||
| 194 | extern int print(char*, ...); | ||
| 195 | extern char* seprint(char*, char*, char*, ...); | ||
| 196 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 197 | extern int snprint(char*, int, char*, ...); | ||
| 198 | extern int vsnprint(char*, int, char*, va_list); | ||
| 199 | extern char* smprint(char*, ...); | ||
| 200 | extern char* vsmprint(char*, va_list); | ||
| 201 | extern int sprint(char*, char*, ...); | ||
| 202 | extern int fprint(int, char*, ...); | ||
| 203 | extern int vfprint(int, char*, va_list); | ||
| 204 | |||
| 205 | extern int runesprint(Rune*, char*, ...); | ||
| 206 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 207 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 208 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 209 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 210 | extern Rune* runesmprint(char*, ...); | ||
| 211 | extern Rune* runevsmprint(char*, va_list); | ||
| 212 | |||
| 213 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 214 | extern int fmtfdflush(Fmt*); | ||
| 215 | extern int fmtstrinit(Fmt*); | ||
| 216 | extern char* fmtstrflush(Fmt*); | ||
| 217 | extern int runefmtstrinit(Fmt*); | ||
| 218 | extern Rune* runefmtstrflush(Fmt*); | ||
| 219 | |||
| 220 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 221 | extern int dofmt(Fmt*, char*); | ||
| 222 | extern int dorfmt(Fmt*, Rune*); | ||
| 223 | extern int fmtprint(Fmt*, char*, ...); | ||
| 224 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 225 | extern int fmtrune(Fmt*, int); | ||
| 226 | extern int fmtstrcpy(Fmt*, char*); | ||
| 227 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 228 | /* | ||
| 229 | * error string for %r | ||
| 230 | * supplied on per os basis, not part of fmt library | ||
| 231 | */ | ||
| 232 | extern int errfmt(Fmt *f); | ||
| 233 | |||
| 234 | /* | ||
| 235 | * quoted strings | ||
| 236 | */ | ||
| 237 | extern char *unquotestrdup(char*); | ||
| 238 | extern Rune *unquoterunestrdup(Rune*); | ||
| 239 | extern char *quotestrdup(char*); | ||
| 240 | extern Rune *quoterunestrdup(Rune*); | ||
| 241 | extern int quotestrfmt(Fmt*); | ||
| 242 | extern int quoterunestrfmt(Fmt*); | ||
| 243 | extern void quotefmtinstall(void); | ||
| 244 | extern int (*doquote)(int); | ||
| 245 | |||
| 246 | /* | ||
| 247 | * random number | ||
| 248 | */ | ||
| 249 | |||
| 250 | extern int nrand(int); | ||
| 251 | extern ulong truerand(void); | ||
| 252 | extern ulong ntruerand(ulong); | ||
| 253 | |||
| 254 | /* | ||
| 255 | * math | ||
| 256 | */ | ||
| 257 | extern int isNaN(double); | ||
| 258 | extern int isInf(double, int); | ||
| 259 | extern double pow(double, double); | ||
| 260 | |||
| 261 | /* | ||
| 262 | * Time-of-day | ||
| 263 | */ | ||
| 264 | |||
| 265 | typedef struct Tm Tm; | ||
| 266 | struct Tm { | ||
| 267 | int sec; | ||
| 268 | int min; | ||
| 269 | int hour; | ||
| 270 | int mday; | ||
| 271 | int mon; | ||
| 272 | int year; | ||
| 273 | int wday; | ||
| 274 | int yday; | ||
| 275 | char zone[4]; | ||
| 276 | int tzoff; | ||
| 277 | }; | ||
| 278 | extern vlong osnsec(void); | ||
| 279 | #define nsec osnsec | ||
| 280 | |||
| 281 | /* | ||
| 282 | * one-of-a-kind | ||
| 283 | */ | ||
| 284 | extern void _assert(char*); | ||
| 285 | extern double charstod(int(*)(void*), void*); | ||
| 286 | extern char* cleanname(char*); | ||
| 287 | extern double frexp(double, int*); | ||
| 288 | extern uintptr getcallerpc(void*); | ||
| 289 | extern int getfields(char*, char**, int, int, char*); | ||
| 290 | extern char* getuser(void); | ||
| 291 | extern char* getwd(char*, int); | ||
| 292 | extern double ipow10(int); | ||
| 293 | extern double ldexp(double, int); | ||
| 294 | extern double modf(double, double*); | ||
| 295 | extern void perror(const char*); | ||
| 296 | extern double pow10(int); | ||
| 297 | extern uvlong strtoull(const char*, char**, int); | ||
| 298 | extern void sysfatal(char*, ...); | ||
| 299 | extern int dec64(uchar*, int, char*, int); | ||
| 300 | extern int enc64(char*, int, uchar*, int); | ||
| 301 | extern int dec32(uchar*, int, char*, int); | ||
| 302 | extern int enc32(char*, int, uchar*, int); | ||
| 303 | extern int dec16(uchar*, int, char*, int); | ||
| 304 | extern int enc16(char*, int, uchar*, int); | ||
| 305 | extern int encodefmt(Fmt*); | ||
| 306 | |||
| 307 | /* | ||
| 308 | * synchronization | ||
| 309 | */ | ||
| 310 | typedef | ||
| 311 | struct Lock { | ||
| 312 | int val; | ||
| 313 | int pid; | ||
| 314 | } Lock; | ||
| 315 | |||
| 316 | extern int _tas(int*); | ||
| 317 | |||
| 318 | extern void lock(Lock*); | ||
| 319 | extern void unlock(Lock*); | ||
| 320 | extern int canlock(Lock*); | ||
| 321 | |||
| 322 | typedef struct QLock QLock; | ||
| 323 | struct QLock | ||
| 324 | { | ||
| 325 | Lock use; /* to access Qlock structure */ | ||
| 326 | Proc *head; /* next process waiting for object */ | ||
| 327 | Proc *tail; /* last process waiting for object */ | ||
| 328 | int locked; /* flag */ | ||
| 329 | }; | ||
| 330 | |||
| 331 | extern void qlock(QLock*); | ||
| 332 | extern void qunlock(QLock*); | ||
| 333 | extern int canqlock(QLock*); | ||
| 334 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 335 | |||
| 336 | typedef | ||
| 337 | struct RWLock | ||
| 338 | { | ||
| 339 | Lock l; /* Lock modify lock */ | ||
| 340 | QLock x; /* Mutual exclusion lock */ | ||
| 341 | QLock k; /* Lock for waiting writers */ | ||
| 342 | int readers; /* Count of readers in lock */ | ||
| 343 | } RWLock; | ||
| 344 | |||
| 345 | extern int canrlock(RWLock*); | ||
| 346 | extern int canwlock(RWLock*); | ||
| 347 | extern void rlock(RWLock*); | ||
| 348 | extern void runlock(RWLock*); | ||
| 349 | extern void wlock(RWLock*); | ||
| 350 | extern void wunlock(RWLock*); | ||
| 351 | |||
| 352 | /* | ||
| 353 | * network dialing | ||
| 354 | */ | ||
| 355 | #define NETPATHLEN 40 | ||
| 356 | |||
| 357 | /* | ||
| 358 | * system calls | ||
| 359 | * | ||
| 360 | */ | ||
| 361 | |||
| 362 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 363 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 364 | #define ERRMAX 128 /* max length of error string */ | ||
| 365 | |||
| 366 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 367 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 368 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 369 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 370 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 371 | #define MCACHE 0x0010 /* cache some data */ | ||
| 372 | #define MMASK 0x0017 /* all bits on */ | ||
| 373 | |||
| 374 | #define OREAD 0 /* open for read */ | ||
| 375 | #define OWRITE 1 /* write */ | ||
| 376 | #define ORDWR 2 /* read and write */ | ||
| 377 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 378 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 379 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 380 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 381 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 382 | |||
| 383 | #define AEXIST 0 /* accessible: exists */ | ||
| 384 | #define AEXEC 1 /* execute access */ | ||
| 385 | #define AWRITE 2 /* write access */ | ||
| 386 | #define AREAD 4 /* read access */ | ||
| 387 | |||
| 388 | /* bits in Qid.type */ | ||
| 389 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 390 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 391 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 392 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 393 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 394 | #define QTFILE 0x00 /* plain file */ | ||
| 395 | |||
| 396 | /* bits in Dir.mode */ | ||
| 397 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 398 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 399 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 400 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 401 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 402 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 403 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 404 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 405 | |||
| 406 | typedef | ||
| 407 | struct Qid | ||
| 408 | { | ||
| 409 | uvlong path; | ||
| 410 | ulong vers; | ||
| 411 | uchar type; | ||
| 412 | } Qid; | ||
| 413 | |||
| 414 | typedef | ||
| 415 | struct Dir { | ||
| 416 | /* system-modified data */ | ||
| 417 | ushort type; /* server type */ | ||
| 418 | uint dev; /* server subtype */ | ||
| 419 | /* file data */ | ||
| 420 | Qid qid; /* unique id from server */ | ||
| 421 | ulong mode; /* permissions */ | ||
| 422 | ulong atime; /* last read time */ | ||
| 423 | ulong mtime; /* last write time */ | ||
| 424 | vlong length; /* file length */ | ||
| 425 | char *name; /* last element of path */ | ||
| 426 | char *uid; /* owner name */ | ||
| 427 | char *gid; /* group name */ | ||
| 428 | char *muid; /* last modifier name */ | ||
| 429 | } Dir; | ||
| 430 | |||
| 431 | extern Dir* dirstat(char*); | ||
| 432 | extern Dir* dirfstat(int); | ||
| 433 | extern int dirwstat(char*, Dir*); | ||
| 434 | extern int dirfwstat(int, Dir*); | ||
| 435 | extern long dirread(int, Dir**); | ||
| 436 | extern void nulldir(Dir*); | ||
| 437 | extern long dirreadall(int, Dir**); | ||
| 438 | |||
| 439 | typedef | ||
| 440 | struct Waitmsg | ||
| 441 | { | ||
| 442 | int pid; /* of loved one */ | ||
| 443 | ulong time[3]; /* of loved one & descendants */ | ||
| 444 | char *msg; | ||
| 445 | } Waitmsg; | ||
| 446 | |||
| 447 | extern void _exits(char*); | ||
| 448 | |||
| 449 | extern void exits(char*); | ||
| 450 | extern int create(char*, int, int); | ||
| 451 | extern int errstr(char*, uint); | ||
| 452 | |||
| 453 | extern void perror(const char*); | ||
| 454 | extern long readn(int, void*, long); | ||
| 455 | extern int remove(const char*); | ||
| 456 | extern void rerrstr(char*, uint); | ||
| 457 | extern vlong seek(int, vlong, int); | ||
| 458 | extern int segflush(void*, ulong); | ||
| 459 | extern void werrstr(char*, ...); | ||
| 460 | |||
| 461 | extern char *argv0; | ||
| 462 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 463 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 464 | argc--, argv++) {\ | ||
| 465 | char *_args, *_argt;\ | ||
| 466 | Rune _argc;\ | ||
| 467 | _args = &argv[0][1];\ | ||
| 468 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 469 | argc--; argv++; break;\ | ||
| 470 | }\ | ||
| 471 | _argc = 0;\ | ||
| 472 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 473 | switch(_argc) | ||
| 474 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 475 | #define ARGF() (_argt=_args, _args="",\ | ||
| 476 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 477 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 478 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 479 | |||
| 480 | #define ARGC() _argc | ||
| 481 | |||
| 482 | /* | ||
| 483 | * Extensions for Inferno to basic libc.h | ||
| 484 | */ | ||
| 485 | |||
| 486 | #define setbinmode() | ||
| 487 | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | # | ||
| 2 | # needed for the build process | ||
| 3 | # | ||
| 4 | set path=( $path `pwd`/MacOSX/power/bin ) | ||
| 5 | |||
| 6 | setenv EMU "-r`pwd` -g1024x768" | ||
| 7 | |||
| 8 | setenv ROOT `pwd` | ||
| 9 | setenv SYSHOST MacOSX | ||
| 10 | setenv OBJTYPE power | ||
| 11 | setenv ACIDLIB $ROOT/lib/acid | ||
| 12 | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | This Inferno® distribution includes software from various sources and | ||
| 2 | different portions are therefore subject to different licence terms. | ||
| 3 | The most stringent is the GNU Public License (version 2), which governs the collection. | ||
| 4 | Individual components might have their own NOTICE and licence files (LICENCE | ||
| 5 | or COPYING) that cover their content. All of them allow modification and redistribution. | ||
| 6 | They are all compatible with the GPLv2. | ||
| 7 | |||
| 8 | The following copyright notice covers the contents of this | ||
| 9 | distribution unless otherwise specified by a given file, directory, or | ||
| 10 | directory tree: | ||
| 11 | |||
| 12 | Inferno® Copyright © 1996-1999 Lucent Technologies Inc. All rights reserved. | ||
| 13 | Inferno revisions Copyright © 1997-1999 Vita Nuova Limited. All rights reserved. | ||
| 14 | Inferno revisions Copyright © 2000-2007 Vita Nuova Holdings Limited. All rights reserved. | ||
| 15 | Inferno new material Copyright © 2000-2007 Vita Nuova Holdings Limited. All rights reserved. | ||
| 16 | |||
| 17 | Inferno, Styx, Dis and Limbo are registered trademarks of Vita Nuova Holdings Limited in the USA and other countries. | ||
| 18 | Plan 9 is a registered trademark of Lucent Technologies Inc. | ||
| 19 | |||
| 20 | This program is free software; you can redistribute it and/or modify | ||
| 21 | it under the terms of the GNU General Public License (`GPL') as published by | ||
| 22 | the Free Software Foundation; either version 2 of the License, or | ||
| 23 | (at your option) any later version. | ||
| 24 | |||
| 25 | This program is distributed in the hope that it will be useful, | ||
| 26 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 27 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 28 | GNU General Public License for more details. | ||
| 29 | |||
| 30 | You should have received a copy of the GNU General Public License | ||
| 31 | along with this program; if not, write to the Free Software | ||
| 32 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 9 | */ | ||
| 10 | typedef struct FPU FPU; | ||
| 11 | struct FPU | ||
| 12 | { | ||
| 13 | uchar env[28]; | ||
| 14 | }; | ||
| 15 | |||
| 16 | #define KSTACK (32 * 1024) | ||
| 17 | |||
| 18 | static __inline Proc *getup(void) { | ||
| 19 | Proc *p; | ||
| 20 | __asm__( "movl %%esp, %%eax\n\t" | ||
| 21 | : "=a" (p) | ||
| 22 | ); | ||
| 23 | return *(Proc **)((unsigned long)p & ~(KSTACK - 1)); | ||
| 24 | }; | ||
| 25 | |||
| 26 | #define up (getup()) | ||
| 27 | |||
| 28 | typedef sigjmp_buf osjmpbuf; | ||
| 29 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| 30 | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * Linux 386 fpu support | ||
| 3 | * Mimic Plan9 floating point support | ||
| 4 | */ | ||
| 5 | |||
| 6 | static void | ||
| 7 | setfcr(ulong fcr) | ||
| 8 | { | ||
| 9 | __asm__( "xorb $0x3f, %%al\n\t" | ||
| 10 | "pushw %%ax\n\t" | ||
| 11 | "fwait\n\t" | ||
| 12 | "fldcw (%%esp)\n\t" | ||
| 13 | "popw %%ax\n\t" | ||
| 14 | : /* no output */ | ||
| 15 | : "al" (fcr) | ||
| 16 | ); | ||
| 17 | } | ||
| 18 | |||
| 19 | static ulong | ||
| 20 | getfcr(void) | ||
| 21 | { | ||
| 22 | ulong fcr = 0; | ||
| 23 | |||
| 24 | __asm__( "pushl %%eax\n\t" | ||
| 25 | "fwait\n\t" | ||
| 26 | "fstcw (%%esp)\n\t" | ||
| 27 | "popl %%eax\n\t" | ||
| 28 | "xorb $0x3f, %%al\n\t" | ||
| 29 | : "=a" (fcr) | ||
| 30 | : "eax" (fcr) | ||
| 31 | ); | ||
| 32 | return fcr; | ||
| 33 | } | ||
| 34 | |||
| 35 | static ulong | ||
| 36 | getfsr(void) | ||
| 37 | { | ||
| 38 | ulong fsr = -1; | ||
| 39 | |||
| 40 | __asm__( "fwait\n\t" | ||
| 41 | "fstsw (%%eax)\n\t" | ||
| 42 | "movl (%%eax), %%eax\n\t" | ||
| 43 | "andl $0xffff, %%eax\n\t" | ||
| 44 | : "=a" (fsr) | ||
| 45 | : "eax" (&fsr) | ||
| 46 | ); | ||
| 47 | return fsr; | ||
| 48 | } | ||
| 49 | |||
| 50 | static void | ||
| 51 | setfsr(ulong fsr) | ||
| 52 | { | ||
| 53 | __asm__("fclex\n\t"); | ||
| 54 | } | ||
| 55 | |||
| 56 | /* FCR */ | ||
| 57 | #define FPINEX (1<<5) | ||
| 58 | #define FPUNFL ((1<<4)|(1<<1)) | ||
| 59 | #define FPOVFL (1<<3) | ||
| 60 | #define FPZDIV (1<<2) | ||
| 61 | #define FPINVAL (1<<0) | ||
| 62 | #define FPRNR (0<<10) | ||
| 63 | #define FPRZ (3<<10) | ||
| 64 | #define FPRPINF (2<<10) | ||
| 65 | #define FPRNINF (1<<10) | ||
| 66 | #define FPRMASK (3<<10) | ||
| 67 | #define FPPEXT (3<<8) | ||
| 68 | #define FPPSGL (0<<8) | ||
| 69 | #define FPPDBL (2<<8) | ||
| 70 | #define FPPMASK (3<<8) | ||
| 71 | /* FSR */ | ||
| 72 | #define FPAINEX FPINEX | ||
| 73 | #define FPAOVFL FPOVFL | ||
| 74 | #define FPAUNFL FPUNFL | ||
| 75 | #define FPAZDIV FPZDIV | ||
| 76 | #define FPAINVAL FPINVAL | ||
| @@ -0,0 +1,476 @@ | |||
| 1 | #include <sys/types.h> | ||
| 2 | #include <sys/endian.h> | ||
| 3 | #include <sys/stat.h> | ||
| 4 | #include <stdint.h> | ||
| 5 | #include <stdlib.h> | ||
| 6 | #include <stdarg.h> | ||
| 7 | #include <unistd.h> | ||
| 8 | #include <errno.h> | ||
| 9 | #include <string.h> | ||
| 10 | #include <math.h> | ||
| 11 | #include <fcntl.h> | ||
| 12 | #include <setjmp.h> | ||
| 13 | #include <float.h> | ||
| 14 | #include <time.h> | ||
| 15 | |||
| 16 | #define getwd infgetwd | ||
| 17 | |||
| 18 | #define round infround | ||
| 19 | #define fmax inffmax | ||
| 20 | #define log2 inflog2 | ||
| 21 | |||
| 22 | #ifndef EMU | ||
| 23 | typedef struct Proc Proc; | ||
| 24 | #endif | ||
| 25 | |||
| 26 | /* | ||
| 27 | * math module dtoa | ||
| 28 | */ | ||
| 29 | #if _BYTE_ORDER == _LITTLE_ENDIAN | ||
| 30 | #define __LITTLE_ENDIAN | ||
| 31 | #endif | ||
| 32 | |||
| 33 | #define nil ((void*)0) | ||
| 34 | |||
| 35 | typedef unsigned char uchar; | ||
| 36 | typedef signed char schar; | ||
| 37 | #if 0 /* XXX: uwe: already defined in <sys/types.h> */ | ||
| 38 | typedef unsigned long ulong; | ||
| 39 | #endif | ||
| 40 | |||
| 41 | typedef int64_t vlong; | ||
| 42 | typedef uint64_t uvlong; | ||
| 43 | |||
| 44 | typedef uint8_t u8int; | ||
| 45 | typedef uint16_t u16int; | ||
| 46 | typedef uint32_t u32int; | ||
| 47 | typedef uvlong u64int; | ||
| 48 | |||
| 49 | typedef uintptr_t uintptr; | ||
| 50 | |||
| 51 | typedef signed char int8; | ||
| 52 | typedef unsigned char uint8; | ||
| 53 | typedef short int16; | ||
| 54 | typedef unsigned short uint16; | ||
| 55 | typedef int int32; | ||
| 56 | typedef unsigned int uint32; | ||
| 57 | typedef long long int64; | ||
| 58 | typedef unsigned long long uint64; | ||
| 59 | |||
| 60 | typedef unsigned short Rune; | ||
| 61 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 62 | |||
| 63 | |||
| 64 | #define USED(x) if(x){}else{} | ||
| 65 | #define SET(x) | ||
| 66 | |||
| 67 | #undef nelem | ||
| 68 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 69 | #undef offsetof | ||
| 70 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 71 | #undef assert | ||
| 72 | #define assert(x) if(x){}else _assert(#x) | ||
| 73 | |||
| 74 | /* | ||
| 75 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 76 | */ | ||
| 77 | |||
| 78 | extern char* strecpy(char*, char*, char*); | ||
| 79 | extern char* strdup(const char*); | ||
| 80 | extern int cistrncmp(char*, char*, int); | ||
| 81 | extern int cistrcmp(char*, char*); | ||
| 82 | extern char* cistrstr(char*, char*); | ||
| 83 | extern int tokenize(char*, char**, int); | ||
| 84 | |||
| 85 | enum | ||
| 86 | { | ||
| 87 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 88 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 89 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 90 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 91 | }; | ||
| 92 | |||
| 93 | /* | ||
| 94 | * rune routines | ||
| 95 | */ | ||
| 96 | extern int runetochar(char*, Rune*); | ||
| 97 | extern int chartorune(Rune*, char*); | ||
| 98 | extern int runelen(long); | ||
| 99 | extern int runenlen(Rune*, int); | ||
| 100 | extern int fullrune(char*, int); | ||
| 101 | extern int utflen(char*); | ||
| 102 | extern int utfnlen(char*, long); | ||
| 103 | extern char* utfrune(char*, long); | ||
| 104 | extern char* utfrrune(char*, long); | ||
| 105 | extern char* utfutf(char*, char*); | ||
| 106 | extern char* utfecpy(char*, char*, char*); | ||
| 107 | |||
| 108 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 109 | extern Rune* runestrchr(Rune*, Rune); | ||
| 110 | extern int runestrcmp(Rune*, Rune*); | ||
| 111 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 112 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 113 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 114 | extern Rune* runestrdup(Rune*); | ||
| 115 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 116 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 117 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 118 | extern long runestrlen(Rune*); | ||
| 119 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 120 | |||
| 121 | extern Rune tolowerrune(Rune); | ||
| 122 | extern Rune totitlerune(Rune); | ||
| 123 | extern Rune toupperrune(Rune); | ||
| 124 | extern int isalpharune(Rune); | ||
| 125 | extern int islowerrune(Rune); | ||
| 126 | extern int isspacerune(Rune); | ||
| 127 | extern int istitlerune(Rune); | ||
| 128 | extern int isupperrune(Rune); | ||
| 129 | |||
| 130 | /* | ||
| 131 | * malloc | ||
| 132 | */ | ||
| 133 | extern void* malloc(size_t); | ||
| 134 | extern void* mallocz(ulong, int); | ||
| 135 | extern void free(void*); | ||
| 136 | extern ulong msize(void*); | ||
| 137 | extern void* calloc(size_t, size_t); | ||
| 138 | extern void* realloc(void*, size_t); | ||
| 139 | extern void setmalloctag(void*, ulong); | ||
| 140 | extern void setrealloctag(void*, ulong); | ||
| 141 | extern ulong getmalloctag(void*); | ||
| 142 | extern ulong getrealloctag(void*); | ||
| 143 | extern void* malloctopoolblock(void*); | ||
| 144 | |||
| 145 | /* | ||
| 146 | * print routines | ||
| 147 | */ | ||
| 148 | typedef struct Fmt Fmt; | ||
| 149 | struct Fmt{ | ||
| 150 | uchar runes; /* output buffer is runes or chars? */ | ||
| 151 | void *start; /* of buffer */ | ||
| 152 | void *to; /* current place in the buffer */ | ||
| 153 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 154 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 155 | void *farg; /* to make flush a closure */ | ||
| 156 | int nfmt; /* num chars formatted so far */ | ||
| 157 | va_list args; /* args passed to dofmt */ | ||
| 158 | int r; /* % format Rune */ | ||
| 159 | int width; | ||
| 160 | int prec; | ||
| 161 | ulong flags; | ||
| 162 | }; | ||
| 163 | |||
| 164 | enum{ | ||
| 165 | FmtWidth = 1, | ||
| 166 | FmtLeft = FmtWidth << 1, | ||
| 167 | FmtPrec = FmtLeft << 1, | ||
| 168 | FmtSharp = FmtPrec << 1, | ||
| 169 | FmtSpace = FmtSharp << 1, | ||
| 170 | FmtSign = FmtSpace << 1, | ||
| 171 | FmtZero = FmtSign << 1, | ||
| 172 | FmtUnsigned = FmtZero << 1, | ||
| 173 | FmtShort = FmtUnsigned << 1, | ||
| 174 | FmtLong = FmtShort << 1, | ||
| 175 | FmtVLong = FmtLong << 1, | ||
| 176 | FmtComma = FmtVLong << 1, | ||
| 177 | FmtByte = FmtComma << 1, | ||
| 178 | |||
| 179 | FmtFlag = FmtByte << 1 | ||
| 180 | }; | ||
| 181 | |||
| 182 | extern int print(char*, ...); | ||
| 183 | extern char* seprint(char*, char*, char*, ...); | ||
| 184 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 185 | extern int snprint(char*, int, char*, ...); | ||
| 186 | extern int vsnprint(char*, int, char*, va_list); | ||
| 187 | extern char* smprint(char*, ...); | ||
| 188 | extern char* vsmprint(char*, va_list); | ||
| 189 | extern int sprint(char*, char*, ...); | ||
| 190 | extern int fprint(int, char*, ...); | ||
| 191 | extern int vfprint(int, char*, va_list); | ||
| 192 | |||
| 193 | extern int runesprint(Rune*, char*, ...); | ||
| 194 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 195 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 196 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 197 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 198 | extern Rune* runesmprint(char*, ...); | ||
| 199 | extern Rune* runevsmprint(char*, va_list); | ||
| 200 | |||
| 201 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 202 | extern int fmtfdflush(Fmt*); | ||
| 203 | extern int fmtstrinit(Fmt*); | ||
| 204 | extern char* fmtstrflush(Fmt*); | ||
| 205 | extern int runefmtstrinit(Fmt*); | ||
| 206 | extern Rune* runefmtstrflush(Fmt*); | ||
| 207 | |||
| 208 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 209 | extern int dofmt(Fmt*, char*); | ||
| 210 | extern int dorfmt(Fmt*, Rune*); | ||
| 211 | extern int fmtprint(Fmt*, char*, ...); | ||
| 212 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 213 | extern int fmtrune(Fmt*, int); | ||
| 214 | extern int fmtstrcpy(Fmt*, char*); | ||
| 215 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 216 | /* | ||
| 217 | * error string for %r | ||
| 218 | * supplied on per os basis, not part of fmt library | ||
| 219 | */ | ||
| 220 | extern int errfmt(Fmt *f); | ||
| 221 | |||
| 222 | /* | ||
| 223 | * quoted strings | ||
| 224 | */ | ||
| 225 | extern char *unquotestrdup(char*); | ||
| 226 | extern Rune *unquoterunestrdup(Rune*); | ||
| 227 | extern char *quotestrdup(char*); | ||
| 228 | extern Rune *quoterunestrdup(Rune*); | ||
| 229 | extern int quotestrfmt(Fmt*); | ||
| 230 | extern int quoterunestrfmt(Fmt*); | ||
| 231 | extern void quotefmtinstall(void); | ||
| 232 | extern int (*doquote)(int); | ||
| 233 | |||
| 234 | /* | ||
| 235 | * random number | ||
| 236 | */ | ||
| 237 | extern int nrand(int); | ||
| 238 | extern ulong truerand(void); | ||
| 239 | extern ulong ntruerand(ulong); | ||
| 240 | |||
| 241 | /* | ||
| 242 | * math | ||
| 243 | */ | ||
| 244 | extern int isNaN(double); | ||
| 245 | extern int isInf(double, int); | ||
| 246 | extern double pow(double, double); | ||
| 247 | |||
| 248 | /* | ||
| 249 | * Time-of-day | ||
| 250 | */ | ||
| 251 | |||
| 252 | typedef struct Tm Tm; | ||
| 253 | struct Tm { | ||
| 254 | int sec; | ||
| 255 | int min; | ||
| 256 | int hour; | ||
| 257 | int mday; | ||
| 258 | int mon; | ||
| 259 | int year; | ||
| 260 | int wday; | ||
| 261 | int yday; | ||
| 262 | char zone[4]; | ||
| 263 | int tzoff; | ||
| 264 | }; | ||
| 265 | extern vlong osnsec(void); | ||
| 266 | #define nsec osnsec | ||
| 267 | |||
| 268 | /* | ||
| 269 | * one-of-a-kind | ||
| 270 | */ | ||
| 271 | extern void _assert(char*); | ||
| 272 | extern double charstod(int(*)(void*), void*); | ||
| 273 | extern char* cleanname(char*); | ||
| 274 | extern double frexp(double, int*); | ||
| 275 | extern uintptr getcallerpc(void*); | ||
| 276 | extern int getfields(char*, char**, int, int, char*); | ||
| 277 | extern char* getuser(void); | ||
| 278 | extern char* getwd(char*, int); | ||
| 279 | extern double ipow10(int); | ||
| 280 | extern double ldexp(double, int); | ||
| 281 | extern double modf(double, double*); | ||
| 282 | #define pow10 infpow10 | ||
| 283 | extern double pow10(int); | ||
| 284 | extern vlong strtoll(const char*, char**, int); | ||
| 285 | #define qsort infqsort | ||
| 286 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 287 | extern uvlong strtoull(const char*, char**, int); | ||
| 288 | extern void sysfatal(char*, ...); | ||
| 289 | extern int dec64(uchar*, int, char*, int); | ||
| 290 | extern int enc64(char*, int, uchar*, int); | ||
| 291 | extern int dec32(uchar*, int, char*, int); | ||
| 292 | extern int enc32(char*, int, uchar*, int); | ||
| 293 | extern int dec16(uchar*, int, char*, int); | ||
| 294 | extern int enc16(char*, int, uchar*, int); | ||
| 295 | extern int encodefmt(Fmt*); | ||
| 296 | |||
| 297 | /* | ||
| 298 | * synchronization | ||
| 299 | */ | ||
| 300 | typedef | ||
| 301 | struct Lock { | ||
| 302 | int val; | ||
| 303 | int pid; | ||
| 304 | } Lock; | ||
| 305 | |||
| 306 | extern int _tas(int*); | ||
| 307 | |||
| 308 | extern void lock(Lock*); | ||
| 309 | extern void unlock(Lock*); | ||
| 310 | extern int canlock(Lock*); | ||
| 311 | |||
| 312 | typedef struct QLock QLock; | ||
| 313 | struct QLock | ||
| 314 | { | ||
| 315 | Lock use; /* to access Qlock structure */ | ||
| 316 | Proc *head; /* next process waiting for object */ | ||
| 317 | Proc *tail; /* last process waiting for object */ | ||
| 318 | int locked; /* flag */ | ||
| 319 | }; | ||
| 320 | |||
| 321 | extern void qlock(QLock*); | ||
| 322 | extern void qunlock(QLock*); | ||
| 323 | extern int canqlock(QLock*); | ||
| 324 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 325 | |||
| 326 | typedef | ||
| 327 | struct RWLock | ||
| 328 | { | ||
| 329 | Lock l; /* Lock modify lock */ | ||
| 330 | QLock x; /* Mutual exclusion lock */ | ||
| 331 | QLock k; /* Lock for waiting writers */ | ||
| 332 | int readers; /* Count of readers in lock */ | ||
| 333 | } RWLock; | ||
| 334 | |||
| 335 | extern int canrlock(RWLock*); | ||
| 336 | extern int canwlock(RWLock*); | ||
| 337 | extern void rlock(RWLock*); | ||
| 338 | extern void runlock(RWLock*); | ||
| 339 | extern void wlock(RWLock*); | ||
| 340 | extern void wunlock(RWLock*); | ||
| 341 | |||
| 342 | /* | ||
| 343 | * network dialing | ||
| 344 | */ | ||
| 345 | #define NETPATHLEN 40 | ||
| 346 | |||
| 347 | /* | ||
| 348 | * system calls | ||
| 349 | * | ||
| 350 | */ | ||
| 351 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 352 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 353 | #define ERRMAX 128 /* max length of error string */ | ||
| 354 | |||
| 355 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 356 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 357 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 358 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 359 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 360 | #define MCACHE 0x0010 /* cache some data */ | ||
| 361 | #define MMASK 0x0017 /* all bits on */ | ||
| 362 | |||
| 363 | #define OREAD 0 /* open for read */ | ||
| 364 | #define OWRITE 1 /* write */ | ||
| 365 | #define ORDWR 2 /* read and write */ | ||
| 366 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 367 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 368 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 369 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 370 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 371 | |||
| 372 | #define AEXIST 0 /* accessible: exists */ | ||
| 373 | #define AEXEC 1 /* execute access */ | ||
| 374 | #define AWRITE 2 /* write access */ | ||
| 375 | #define AREAD 4 /* read access */ | ||
| 376 | |||
| 377 | /* bits in Qid.type */ | ||
| 378 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 379 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 380 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 381 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 382 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 383 | #define QTFILE 0x00 /* plain file */ | ||
| 384 | |||
| 385 | /* bits in Dir.mode */ | ||
| 386 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 387 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 388 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 389 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 390 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 391 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 392 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 393 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 394 | |||
| 395 | typedef | ||
| 396 | struct Qid | ||
| 397 | { | ||
| 398 | uvlong path; | ||
| 399 | ulong vers; | ||
| 400 | uchar type; | ||
| 401 | } Qid; | ||
| 402 | |||
| 403 | typedef | ||
| 404 | struct Dir { | ||
| 405 | /* system-modified data */ | ||
| 406 | ushort type; /* server type */ | ||
| 407 | uint dev; /* server subtype */ | ||
| 408 | /* file data */ | ||
| 409 | Qid qid; /* unique id from server */ | ||
| 410 | ulong mode; /* permissions */ | ||
| 411 | ulong atime; /* last read time */ | ||
| 412 | ulong mtime; /* last write time */ | ||
| 413 | vlong length; /* file length */ | ||
| 414 | char *name; /* last element of path */ | ||
| 415 | char *uid; /* owner name */ | ||
| 416 | char *gid; /* group name */ | ||
| 417 | char *muid; /* last modifier name */ | ||
| 418 | } Dir; | ||
| 419 | |||
| 420 | extern Dir* dirstat(char*); | ||
| 421 | extern Dir* dirfstat(int); | ||
| 422 | extern int dirwstat(char*, Dir*); | ||
| 423 | extern int dirfwstat(int, Dir*); | ||
| 424 | extern long dirread(int, Dir**); | ||
| 425 | extern void nulldir(Dir*); | ||
| 426 | extern long dirreadall(int, Dir**); | ||
| 427 | |||
| 428 | typedef | ||
| 429 | struct Waitmsg | ||
| 430 | { | ||
| 431 | int pid; /* of loved one */ | ||
| 432 | ulong time[3]; /* of loved one & descendants */ | ||
| 433 | char *msg; | ||
| 434 | } Waitmsg; | ||
| 435 | |||
| 436 | extern void _exits(char*); | ||
| 437 | |||
| 438 | extern void exits(char*); | ||
| 439 | extern int create(char*, int, int); | ||
| 440 | extern int errstr(char*, uint); | ||
| 441 | |||
| 442 | extern void perror(const char*); | ||
| 443 | extern long readn(int, void*, long); | ||
| 444 | extern int remove(const char*); | ||
| 445 | extern void rerrstr(char*, uint); | ||
| 446 | extern vlong seek(int, vlong, int); | ||
| 447 | extern int segflush(void*, ulong); | ||
| 448 | extern void werrstr(char*, ...); | ||
| 449 | |||
| 450 | extern char *argv0; | ||
| 451 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 452 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 453 | argc--, argv++) {\ | ||
| 454 | char *_args, *_argt;\ | ||
| 455 | Rune _argc;\ | ||
| 456 | _args = &argv[0][1];\ | ||
| 457 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 458 | argc--; argv++; break;\ | ||
| 459 | }\ | ||
| 460 | _argc = 0;\ | ||
| 461 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 462 | switch(_argc) | ||
| 463 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 464 | #define ARGF() (_argt=_args, _args="",\ | ||
| 465 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 466 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 467 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 468 | |||
| 469 | #define ARGC() _argc | ||
| 470 | |||
| 471 | /* | ||
| 472 | * Extensions for Inferno to basic libc.h | ||
| 473 | */ | ||
| 474 | |||
| 475 | #define setbinmode() | ||
| 476 | |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,24 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 9 | */ | ||
| 10 | typedef struct FPU FPU; | ||
| 11 | struct FPU | ||
| 12 | { | ||
| 13 | uchar env[28]; | ||
| 14 | }; | ||
| 15 | |||
| 16 | extern void sleep(int); | ||
| 17 | |||
| 18 | /* Set up private thread space */ | ||
| 19 | extern __declspec(thread) Proc* up; | ||
| 20 | #define Sleep NTsleep | ||
| 21 | |||
| 22 | typedef jmp_buf osjmpbuf; | ||
| 23 | #define ossetjmp(buf) setjmp(buf) | ||
| 24 | |||
| @@ -0,0 +1,485 @@ | |||
| 1 | #define _POSIX_SOURCE | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <stdarg.h> | ||
| 4 | #include <errno.h> | ||
| 5 | #include <string.h> | ||
| 6 | #include "math.h" | ||
| 7 | #include <fcntl.h> | ||
| 8 | #include <setjmp.h> | ||
| 9 | #include <float.h> | ||
| 10 | #include <time.h> | ||
| 11 | #include <process.h> | ||
| 12 | #include <io.h> | ||
| 13 | #include <direct.h> | ||
| 14 | |||
| 15 | #define getwd infgetwd | ||
| 16 | |||
| 17 | /* do-it-yourself isinf and isnan */ | ||
| 18 | #ifndef isnan | ||
| 19 | #define isnan(x) _isnan(x) | ||
| 20 | #endif | ||
| 21 | #ifndef isinf | ||
| 22 | #define isinf(x) (!_finite(x)) | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #ifndef EMU | ||
| 26 | typedef struct Proc Proc; | ||
| 27 | #endif | ||
| 28 | |||
| 29 | /* | ||
| 30 | * math module dtoa | ||
| 31 | */ | ||
| 32 | #define __LITTLE_ENDIAN | ||
| 33 | |||
| 34 | /* there must be a Win32 header macro for endian-ness!!! */ | ||
| 35 | |||
| 36 | /* | ||
| 37 | * disable various silly warnings | ||
| 38 | * 4018 signed/unsigned comparison | ||
| 39 | * 4245 signed/unsigned conversion | ||
| 40 | * 4244 long to char conversion | ||
| 41 | * 4068 unknown pragma | ||
| 42 | * 4090 different volatile quals | ||
| 43 | * 4554 operator precedence | ||
| 44 | * 4146 unary - on unsigned type | ||
| 45 | * 4996 `deprecated' functions: they often suggest non-portable replacements | ||
| 46 | */ | ||
| 47 | #pragma warning( disable : 4305 4244 4102 4761 4018 4245 4244 4068 4090 4554 4146 4996) | ||
| 48 | |||
| 49 | #define nil ((void*)0) | ||
| 50 | |||
| 51 | typedef unsigned char uchar; | ||
| 52 | typedef unsigned int uint; | ||
| 53 | typedef unsigned long ulong; | ||
| 54 | typedef signed char schar; | ||
| 55 | typedef unsigned short ushort; | ||
| 56 | typedef unsigned short Rune; | ||
| 57 | typedef __int64 vlong; | ||
| 58 | typedef unsigned __int64 uvlong; | ||
| 59 | typedef unsigned int u32int; | ||
| 60 | typedef uvlong u64int; | ||
| 61 | |||
| 62 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 63 | typedef unsigned short u16int; | ||
| 64 | typedef unsigned char u8int; | ||
| 65 | typedef unsigned long uintptr; | ||
| 66 | |||
| 67 | typedef signed char int8; | ||
| 68 | typedef unsigned char uint8; | ||
| 69 | typedef short int16; | ||
| 70 | typedef unsigned short uint16; | ||
| 71 | typedef int int32; | ||
| 72 | typedef unsigned int uint32; | ||
| 73 | typedef long long int64; | ||
| 74 | typedef unsigned long long uint64; | ||
| 75 | |||
| 76 | #define USED(x) if(x){}else{} | ||
| 77 | #define SET(x) | ||
| 78 | |||
| 79 | #undef nelem | ||
| 80 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 81 | #undef offsetof | ||
| 82 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 83 | #undef assert | ||
| 84 | #define assert(x) if(x){}else _assert("x") | ||
| 85 | |||
| 86 | /* | ||
| 87 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 88 | */ | ||
| 89 | |||
| 90 | extern char* strecpy(char*, char*, char*); | ||
| 91 | extern char* strdup(const char*); | ||
| 92 | extern int cistrncmp(char*, char*, int); | ||
| 93 | extern int cistrcmp(char*, char*); | ||
| 94 | extern char* cistrstr(char*, char*); | ||
| 95 | extern int tokenize(char*, char**, int); | ||
| 96 | extern vlong strtoll(const char*, char**, int); | ||
| 97 | #define qsort infqsort | ||
| 98 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 99 | extern uvlong strtoull(const char*, char**, int); | ||
| 100 | |||
| 101 | enum | ||
| 102 | { | ||
| 103 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 104 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 105 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 106 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 107 | }; | ||
| 108 | |||
| 109 | /* | ||
| 110 | * rune routines | ||
| 111 | */ | ||
| 112 | extern int runetochar(char*, Rune*); | ||
| 113 | extern int chartorune(Rune*, char*); | ||
| 114 | extern int runelen(long); | ||
| 115 | extern int runenlen(Rune*, int); | ||
| 116 | extern int fullrune(char*, int); | ||
| 117 | extern int utflen(char*); | ||
| 118 | extern int utfnlen(char*, long); | ||
| 119 | extern char* utfrune(char*, long); | ||
| 120 | extern char* utfrrune(char*, long); | ||
| 121 | extern char* utfutf(char*, char*); | ||
| 122 | extern char* utfecpy(char*, char*, char*); | ||
| 123 | |||
| 124 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 125 | extern Rune* runestrchr(Rune*, Rune); | ||
| 126 | extern int runestrcmp(Rune*, Rune*); | ||
| 127 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 128 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 129 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 130 | extern Rune* runestrdup(Rune*); | ||
| 131 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 132 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 133 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 134 | extern long runestrlen(Rune*); | ||
| 135 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 136 | |||
| 137 | extern Rune tolowerrune(Rune); | ||
| 138 | extern Rune totitlerune(Rune); | ||
| 139 | extern Rune toupperrune(Rune); | ||
| 140 | extern int isalpharune(Rune); | ||
| 141 | extern int islowerrune(Rune); | ||
| 142 | extern int isspacerune(Rune); | ||
| 143 | extern int istitlerune(Rune); | ||
| 144 | extern int isupperrune(Rune); | ||
| 145 | |||
| 146 | /* | ||
| 147 | * malloc | ||
| 148 | */ | ||
| 149 | extern void* malloc(size_t); | ||
| 150 | extern void* mallocz(ulong, int); | ||
| 151 | extern void free(void*); | ||
| 152 | extern ulong msize(void*); | ||
| 153 | extern void* calloc(size_t, size_t); | ||
| 154 | extern void* realloc(void*, size_t); | ||
| 155 | extern void setmalloctag(void*, ulong); | ||
| 156 | extern void setrealloctag(void*, ulong); | ||
| 157 | extern ulong getmalloctag(void*); | ||
| 158 | extern ulong getrealloctag(void*); | ||
| 159 | extern void* malloctopoolblock(void*); | ||
| 160 | |||
| 161 | /* | ||
| 162 | * print routines | ||
| 163 | */ | ||
| 164 | typedef struct Fmt Fmt; | ||
| 165 | struct Fmt{ | ||
| 166 | uchar runes; /* output buffer is runes or chars? */ | ||
| 167 | void *start; /* of buffer */ | ||
| 168 | void *to; /* current place in the buffer */ | ||
| 169 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 170 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 171 | void *farg; /* to make flush a closure */ | ||
| 172 | int nfmt; /* num chars formatted so far */ | ||
| 173 | va_list args; /* args passed to dofmt */ | ||
| 174 | int r; /* % format Rune */ | ||
| 175 | int width; | ||
| 176 | int prec; | ||
| 177 | ulong flags; | ||
| 178 | }; | ||
| 179 | |||
| 180 | enum{ | ||
| 181 | FmtWidth = 1, | ||
| 182 | FmtLeft = FmtWidth << 1, | ||
| 183 | FmtPrec = FmtLeft << 1, | ||
| 184 | FmtSharp = FmtPrec << 1, | ||
| 185 | FmtSpace = FmtSharp << 1, | ||
| 186 | FmtSign = FmtSpace << 1, | ||
| 187 | FmtZero = FmtSign << 1, | ||
| 188 | FmtUnsigned = FmtZero << 1, | ||
| 189 | FmtShort = FmtUnsigned << 1, | ||
| 190 | FmtLong = FmtShort << 1, | ||
| 191 | FmtVLong = FmtLong << 1, | ||
| 192 | FmtComma = FmtVLong << 1, | ||
| 193 | FmtByte = FmtComma << 1, | ||
| 194 | |||
| 195 | FmtFlag = FmtByte << 1 | ||
| 196 | }; | ||
| 197 | |||
| 198 | extern int print(char*, ...); | ||
| 199 | extern char* seprint(char*, char*, char*, ...); | ||
| 200 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 201 | extern int snprint(char*, int, char*, ...); | ||
| 202 | extern int vsnprint(char*, int, char*, va_list); | ||
| 203 | extern char* smprint(char*, ...); | ||
| 204 | extern char* vsmprint(char*, va_list); | ||
| 205 | extern int sprint(char*, char*, ...); | ||
| 206 | extern int fprint(int, char*, ...); | ||
| 207 | extern int vfprint(int, char*, va_list); | ||
| 208 | |||
| 209 | extern int runesprint(Rune*, char*, ...); | ||
| 210 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 211 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 212 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 213 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 214 | extern Rune* runesmprint(char*, ...); | ||
| 215 | extern Rune* runevsmprint(char*, va_list); | ||
| 216 | |||
| 217 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 218 | extern int fmtfdflush(Fmt*); | ||
| 219 | extern int fmtstrinit(Fmt*); | ||
| 220 | extern char* fmtstrflush(Fmt*); | ||
| 221 | extern int runefmtstrinit(Fmt*); | ||
| 222 | extern Rune* runefmtstrflush(Fmt*); | ||
| 223 | |||
| 224 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 225 | extern int dofmt(Fmt*, char*); | ||
| 226 | extern int dorfmt(Fmt*, Rune*); | ||
| 227 | extern int fmtprint(Fmt*, char*, ...); | ||
| 228 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 229 | extern int fmtrune(Fmt*, int); | ||
| 230 | extern int fmtstrcpy(Fmt*, char*); | ||
| 231 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 232 | /* | ||
| 233 | * error string for %r | ||
| 234 | * supplied on per os basis, not part of fmt library | ||
| 235 | */ | ||
| 236 | extern int errfmt(Fmt *f); | ||
| 237 | |||
| 238 | /* | ||
| 239 | * quoted strings | ||
| 240 | */ | ||
| 241 | extern char *unquotestrdup(char*); | ||
| 242 | extern Rune *unquoterunestrdup(Rune*); | ||
| 243 | extern char *quotestrdup(char*); | ||
| 244 | extern Rune *quoterunestrdup(Rune*); | ||
| 245 | extern int quotestrfmt(Fmt*); | ||
| 246 | extern int quoterunestrfmt(Fmt*); | ||
| 247 | extern void quotefmtinstall(void); | ||
| 248 | extern int (*doquote)(int); | ||
| 249 | |||
| 250 | /* | ||
| 251 | * random number | ||
| 252 | */ | ||
| 253 | extern ulong truerand(void); | ||
| 254 | extern ulong ntruerand(ulong); | ||
| 255 | |||
| 256 | /* | ||
| 257 | * math | ||
| 258 | */ | ||
| 259 | extern int isNaN(double); | ||
| 260 | extern int isInf(double, int); | ||
| 261 | |||
| 262 | #define PIO2 1.570796326794896619231e0 | ||
| 263 | #define PI (PIO2+PIO2) | ||
| 264 | |||
| 265 | /* | ||
| 266 | * Time-of-day | ||
| 267 | */ | ||
| 268 | |||
| 269 | typedef struct Tm Tm; | ||
| 270 | struct Tm { | ||
| 271 | int sec; | ||
| 272 | int min; | ||
| 273 | int hour; | ||
| 274 | int mday; | ||
| 275 | int mon; | ||
| 276 | int year; | ||
| 277 | int wday; | ||
| 278 | int yday; | ||
| 279 | char zone[4]; | ||
| 280 | int tzoff; | ||
| 281 | }; | ||
| 282 | extern vlong osnsec(void); | ||
| 283 | #define nsec osnsec | ||
| 284 | |||
| 285 | /* | ||
| 286 | * one-of-a-kind | ||
| 287 | */ | ||
| 288 | extern void _assert(char*); | ||
| 289 | extern double charstod(int(*)(void*), void*); | ||
| 290 | extern char* cleanname(char*); | ||
| 291 | extern uintptr getcallerpc(void*); | ||
| 292 | extern int getfields(char*, char**, int, int, char*); | ||
| 293 | extern char* getuser(void); | ||
| 294 | extern char* getuser(void); | ||
| 295 | extern char* getwd(char*, int); | ||
| 296 | extern char* getwd(char*, int); | ||
| 297 | extern double ipow10(int); | ||
| 298 | extern double pow10(int); | ||
| 299 | extern void sysfatal(char*, ...); | ||
| 300 | extern int dec64(uchar*, int, char*, int); | ||
| 301 | extern int enc64(char*, int, uchar*, int); | ||
| 302 | extern int dec32(uchar*, int, char*, int); | ||
| 303 | extern int enc32(char*, int, uchar*, int); | ||
| 304 | extern int dec16(uchar*, int, char*, int); | ||
| 305 | extern int enc16(char*, int, uchar*, int); | ||
| 306 | extern int encodefmt(Fmt*); | ||
| 307 | |||
| 308 | /* | ||
| 309 | * synchronization | ||
| 310 | */ | ||
| 311 | typedef | ||
| 312 | struct Lock { | ||
| 313 | int val; | ||
| 314 | int pid; | ||
| 315 | } Lock; | ||
| 316 | |||
| 317 | extern int _tas(int*); | ||
| 318 | |||
| 319 | extern void lock(Lock*); | ||
| 320 | extern void unlock(Lock*); | ||
| 321 | extern int canlock(Lock*); | ||
| 322 | |||
| 323 | typedef struct QLock QLock; | ||
| 324 | struct QLock | ||
| 325 | { | ||
| 326 | Lock use; /* to access Qlock structure */ | ||
| 327 | Proc *head; /* next process waiting for object */ | ||
| 328 | Proc *tail; /* last process waiting for object */ | ||
| 329 | int locked; /* flag */ | ||
| 330 | }; | ||
| 331 | |||
| 332 | extern void qlock(QLock*); | ||
| 333 | extern void qunlock(QLock*); | ||
| 334 | extern int canqlock(QLock*); | ||
| 335 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 336 | |||
| 337 | typedef | ||
| 338 | struct RWLock | ||
| 339 | { | ||
| 340 | Lock l; /* Lock modify lock */ | ||
| 341 | QLock x; /* Mutual exclusion lock */ | ||
| 342 | QLock k; /* Lock for waiting writers */ | ||
| 343 | int readers; /* Count of readers in lock */ | ||
| 344 | } RWLock; | ||
| 345 | |||
| 346 | extern int canrlock(RWLock*); | ||
| 347 | extern int canwlock(RWLock*); | ||
| 348 | extern void rlock(RWLock*); | ||
| 349 | extern void runlock(RWLock*); | ||
| 350 | extern void wlock(RWLock*); | ||
| 351 | extern void wunlock(RWLock*); | ||
| 352 | |||
| 353 | /* | ||
| 354 | * network dialing | ||
| 355 | */ | ||
| 356 | #define NETPATHLEN 40 | ||
| 357 | |||
| 358 | /* | ||
| 359 | * system calls | ||
| 360 | * | ||
| 361 | */ | ||
| 362 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 363 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 364 | #define ERRMAX 128 /* max length of error string */ | ||
| 365 | |||
| 366 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 367 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 368 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 369 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 370 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 371 | #define MCACHE 0x0010 /* cache some data */ | ||
| 372 | #define MMASK 0x0017 /* all bits on */ | ||
| 373 | |||
| 374 | #define OREAD 0 /* open for read */ | ||
| 375 | #define OWRITE 1 /* write */ | ||
| 376 | #define ORDWR 2 /* read and write */ | ||
| 377 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 378 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 379 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 380 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 381 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 382 | |||
| 383 | #define AEXIST 0 /* accessible: exists */ | ||
| 384 | #define AEXEC 1 /* execute access */ | ||
| 385 | #define AWRITE 2 /* write access */ | ||
| 386 | #define AREAD 4 /* read access */ | ||
| 387 | |||
| 388 | /* bits in Qid.type */ | ||
| 389 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 390 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 391 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 392 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 393 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 394 | #define QTFILE 0x00 /* plain file */ | ||
| 395 | |||
| 396 | /* bits in Dir.mode */ | ||
| 397 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 398 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 399 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 400 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 401 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 402 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 403 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 404 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 405 | |||
| 406 | typedef | ||
| 407 | struct Qid | ||
| 408 | { | ||
| 409 | uvlong path; | ||
| 410 | ulong vers; | ||
| 411 | uchar type; | ||
| 412 | } Qid; | ||
| 413 | |||
| 414 | typedef | ||
| 415 | struct Dir { | ||
| 416 | /* system-modified data */ | ||
| 417 | ushort type; /* server type */ | ||
| 418 | uint dev; /* server subtype */ | ||
| 419 | /* file data */ | ||
| 420 | Qid qid; /* unique id from server */ | ||
| 421 | ulong mode; /* permissions */ | ||
| 422 | ulong atime; /* last read time */ | ||
| 423 | ulong mtime; /* last write time */ | ||
| 424 | vlong length; /* file length */ | ||
| 425 | char *name; /* last element of path */ | ||
| 426 | char *uid; /* owner name */ | ||
| 427 | char *gid; /* group name */ | ||
| 428 | char *muid; /* last modifier name */ | ||
| 429 | } Dir; | ||
| 430 | |||
| 431 | extern Dir* dirstat(char*); | ||
| 432 | extern Dir* dirfstat(int); | ||
| 433 | extern int dirwstat(char*, Dir*); | ||
| 434 | extern int dirfwstat(int, Dir*); | ||
| 435 | extern long dirread(int, Dir**); | ||
| 436 | extern void nulldir(Dir*); | ||
| 437 | extern long dirreadall(int, Dir**); | ||
| 438 | |||
| 439 | typedef | ||
| 440 | struct Waitmsg | ||
| 441 | { | ||
| 442 | int pid; /* of loved one */ | ||
| 443 | ulong time[3]; /* of loved one & descendants */ | ||
| 444 | char *msg; | ||
| 445 | } Waitmsg; | ||
| 446 | |||
| 447 | extern void _exits(char*); | ||
| 448 | |||
| 449 | extern void exits(char*); | ||
| 450 | extern int create(char*, int, int); | ||
| 451 | extern int errstr(char*, uint); | ||
| 452 | |||
| 453 | extern long readn(int, void*, long); | ||
| 454 | extern void rerrstr(char*, uint); | ||
| 455 | extern vlong seek(int, vlong, int); | ||
| 456 | extern void werrstr(char*, ...); | ||
| 457 | |||
| 458 | extern char *argv0; | ||
| 459 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 460 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 461 | argc--, argv++) {\ | ||
| 462 | char *_args, *_argt;\ | ||
| 463 | Rune _argc;\ | ||
| 464 | _args = &argv[0][1];\ | ||
| 465 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 466 | argc--; argv++; break;\ | ||
| 467 | }\ | ||
| 468 | _argc = 0;\ | ||
| 469 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 470 | switch(_argc) | ||
| 471 | #define ARGEND (_argt=0);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 472 | #define ARGF() (_argt=_args, _args="",\ | ||
| 473 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 474 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 475 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 476 | |||
| 477 | #define ARGC() _argc | ||
| 478 | |||
| 479 | /* | ||
| 480 | * Extensions for Inferno to basic libc.h | ||
| 481 | */ | ||
| 482 | |||
| 483 | extern void setbinmode(void); | ||
| 484 | extern void* sbrk(int); | ||
| 485 | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | /* | ||
| 8 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 9 | */ | ||
| 10 | typedef struct FPU FPU; | ||
| 11 | struct FPU | ||
| 12 | { | ||
| 13 | uchar env[28]; | ||
| 14 | }; | ||
| 15 | |||
| 16 | #define KSTACK (32 * 1024) | ||
| 17 | |||
| 18 | static __inline Proc *getup(void) { | ||
| 19 | Proc *p; | ||
| 20 | __asm__( "movl %%esp, %%eax\n\t" | ||
| 21 | : "=a" (p) | ||
| 22 | ); | ||
| 23 | return *(Proc **)((unsigned long)p & ~(KSTACK - 1)); | ||
| 24 | }; | ||
| 25 | |||
| 26 | #define up (getup()) | ||
| 27 | |||
| 28 | typedef sigjmp_buf osjmpbuf; | ||
| 29 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| 30 | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | /* | ||
| 2 | * 386 fpu support | ||
| 3 | * Mimic Plan9 floating point support | ||
| 4 | */ | ||
| 5 | |||
| 6 | static void | ||
| 7 | setfcr(ulong fcr) | ||
| 8 | { | ||
| 9 | __asm__( "xorb $0x3f, %%al\n\t" | ||
| 10 | "pushw %%ax\n\t" | ||
| 11 | "fwait\n\t" | ||
| 12 | "fldcw (%%esp)\n\t" | ||
| 13 | "popw %%ax\n\t" | ||
| 14 | : /* no output */ | ||
| 15 | : "al" (fcr) | ||
| 16 | ); | ||
| 17 | } | ||
| 18 | |||
| 19 | static ulong | ||
| 20 | getfcr(void) | ||
| 21 | { | ||
| 22 | ulong fcr = 0; | ||
| 23 | |||
| 24 | __asm__( "pushl %%eax\n\t" | ||
| 25 | "fwait\n\t" | ||
| 26 | "fstcw (%%esp)\n\t" | ||
| 27 | "popl %%eax\n\t" | ||
| 28 | "xorb $0x3f, %%al\n\t" | ||
| 29 | : "=a" (fcr) | ||
| 30 | : "eax" (fcr) | ||
| 31 | ); | ||
| 32 | return fcr; | ||
| 33 | } | ||
| 34 | |||
| 35 | static ulong | ||
| 36 | getfsr(void) | ||
| 37 | { | ||
| 38 | ulong fsr = -1; | ||
| 39 | |||
| 40 | __asm__( "fwait\n\t" | ||
| 41 | "fstsw (%%eax)\n\t" | ||
| 42 | "movl (%%eax), %%eax\n\t" | ||
| 43 | "andl $0xffff, %%eax\n\t" | ||
| 44 | : "=a" (fsr) | ||
| 45 | : "eax" (&fsr) | ||
| 46 | ); | ||
| 47 | return fsr; | ||
| 48 | } | ||
| 49 | |||
| 50 | static void | ||
| 51 | setfsr(ulong fsr) | ||
| 52 | { | ||
| 53 | __asm__("fclex\n\t"); | ||
| 54 | } | ||
| 55 | |||
| 56 | /* FCR */ | ||
| 57 | #define FPINEX (1<<5) | ||
| 58 | #define FPUNFL ((1<<4)|(1<<1)) | ||
| 59 | #define FPOVFL (1<<3) | ||
| 60 | #define FPZDIV (1<<2) | ||
| 61 | #define FPINVAL (1<<0) | ||
| 62 | #define FPRNR (0<<10) | ||
| 63 | #define FPRZ (3<<10) | ||
| 64 | #define FPRPINF (2<<10) | ||
| 65 | #define FPRNINF (1<<10) | ||
| 66 | #define FPRMASK (3<<10) | ||
| 67 | #define FPPEXT (3<<8) | ||
| 68 | #define FPPSGL (0<<8) | ||
| 69 | #define FPPDBL (2<<8) | ||
| 70 | #define FPPMASK (3<<8) | ||
| 71 | /* FSR */ | ||
| 72 | #define FPAINEX FPINEX | ||
| 73 | #define FPAOVFL FPOVFL | ||
| 74 | #define FPAUNFL FPUNFL | ||
| 75 | #define FPAZDIV FPZDIV | ||
| 76 | #define FPAINVAL FPINVAL | ||
| @@ -0,0 +1,473 @@ | |||
| 1 | /* define _BSD_SOURCE to use ISO C, POSIX, and 4.3BSD things. */ | ||
| 2 | #ifndef _BSD_SOURCE | ||
| 3 | #define _BSD_SOURCE | ||
| 4 | #endif | ||
| 5 | /* these aren't really needed because OpenBSD does the right thing and makes off_t 64 bits, full stop */ | ||
| 6 | #define _LARGEFILE64_SOURCE 1 | ||
| 7 | #define _FILE_OFFSET_BITS 64 | ||
| 8 | #include <sys/types.h> | ||
| 9 | #include <sys/stat.h> | ||
| 10 | #include <stdlib.h> | ||
| 11 | #include <stdarg.h> | ||
| 12 | #include <unistd.h> | ||
| 13 | #include <errno.h> | ||
| 14 | #include <string.h> | ||
| 15 | #include "math.h" | ||
| 16 | #include <fcntl.h> | ||
| 17 | #include <setjmp.h> | ||
| 18 | #include <float.h> | ||
| 19 | #include <time.h> | ||
| 20 | |||
| 21 | #define getwd infgetwd | ||
| 22 | |||
| 23 | #define round infround | ||
| 24 | #define fmax inffmax | ||
| 25 | #define log2 inflog2 | ||
| 26 | |||
| 27 | #ifndef EMU | ||
| 28 | typedef struct Proc Proc; | ||
| 29 | #endif | ||
| 30 | |||
| 31 | /* | ||
| 32 | * math module dtoa | ||
| 33 | */ | ||
| 34 | #define __LITTLE_ENDIAN | ||
| 35 | |||
| 36 | #define nil ((void*)0) | ||
| 37 | |||
| 38 | typedef unsigned char uchar; | ||
| 39 | typedef signed char schar; | ||
| 40 | //typedef unsigned long ulong; | ||
| 41 | typedef unsigned short Rune; | ||
| 42 | typedef long long int vlong; | ||
| 43 | typedef unsigned long long int uvlong; | ||
| 44 | typedef unsigned int u32int; | ||
| 45 | typedef uvlong u64int; | ||
| 46 | |||
| 47 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 48 | typedef unsigned short u16int; | ||
| 49 | typedef unsigned char u8int; | ||
| 50 | typedef unsigned long uintptr; | ||
| 51 | |||
| 52 | typedef signed char int8; | ||
| 53 | typedef unsigned char uint8; | ||
| 54 | typedef short int16; | ||
| 55 | typedef unsigned short uint16; | ||
| 56 | typedef int int32; | ||
| 57 | typedef unsigned int uint32; | ||
| 58 | typedef long long int64; | ||
| 59 | typedef unsigned long long uint64; | ||
| 60 | |||
| 61 | #define USED(x) if(x){}else{} | ||
| 62 | #define SET(x) | ||
| 63 | |||
| 64 | #undef nelem | ||
| 65 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 66 | #undef offsetof | ||
| 67 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 68 | #undef assert | ||
| 69 | #define assert(x) if(x){}else _assert("x") | ||
| 70 | |||
| 71 | /* | ||
| 72 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 73 | */ | ||
| 74 | |||
| 75 | extern char* strecpy(char*, char*, char*); | ||
| 76 | extern char* strdup(const char*); | ||
| 77 | extern int cistrncmp(char*, char*, int); | ||
| 78 | extern int cistrcmp(char*, char*); | ||
| 79 | extern char* cistrstr(char*, char*); | ||
| 80 | extern int tokenize(char*, char**, int); | ||
| 81 | |||
| 82 | enum | ||
| 83 | { | ||
| 84 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 85 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 86 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 87 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 88 | }; | ||
| 89 | |||
| 90 | /* | ||
| 91 | * rune routines | ||
| 92 | */ | ||
| 93 | extern int runetochar(char*, Rune*); | ||
| 94 | extern int chartorune(Rune*, char*); | ||
| 95 | extern int runelen(long); | ||
| 96 | extern int runenlen(Rune*, int); | ||
| 97 | extern int fullrune(char*, int); | ||
| 98 | extern int utflen(char*); | ||
| 99 | extern int utfnlen(char*, long); | ||
| 100 | extern char* utfrune(char*, long); | ||
| 101 | extern char* utfrrune(char*, long); | ||
| 102 | extern char* utfutf(char*, char*); | ||
| 103 | extern char* utfecpy(char*, char*, char*); | ||
| 104 | |||
| 105 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 106 | extern Rune* runestrchr(Rune*, Rune); | ||
| 107 | extern int runestrcmp(Rune*, Rune*); | ||
| 108 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 109 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 110 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 111 | extern Rune* runestrdup(Rune*); | ||
| 112 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 113 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 114 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 115 | extern long runestrlen(Rune*); | ||
| 116 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 117 | |||
| 118 | extern Rune tolowerrune(Rune); | ||
| 119 | extern Rune totitlerune(Rune); | ||
| 120 | extern Rune toupperrune(Rune); | ||
| 121 | extern int isalpharune(Rune); | ||
| 122 | extern int islowerrune(Rune); | ||
| 123 | extern int isspacerune(Rune); | ||
| 124 | extern int istitlerune(Rune); | ||
| 125 | extern int isupperrune(Rune); | ||
| 126 | |||
| 127 | /* | ||
| 128 | * malloc | ||
| 129 | */ | ||
| 130 | extern void* malloc(size_t); | ||
| 131 | extern void* mallocz(ulong, int); | ||
| 132 | extern void free(void*); | ||
| 133 | extern ulong msize(void*); | ||
| 134 | extern void* calloc(size_t, size_t); | ||
| 135 | extern void* realloc(void*, size_t); | ||
| 136 | extern void setmalloctag(void*, ulong); | ||
| 137 | extern void setrealloctag(void*, ulong); | ||
| 138 | extern ulong getmalloctag(void*); | ||
| 139 | extern ulong getrealloctag(void*); | ||
| 140 | extern void* malloctopoolblock(void*); | ||
| 141 | |||
| 142 | /* | ||
| 143 | * print routines | ||
| 144 | */ | ||
| 145 | typedef struct Fmt Fmt; | ||
| 146 | struct Fmt{ | ||
| 147 | uchar runes; /* output buffer is runes or chars? */ | ||
| 148 | void *start; /* of buffer */ | ||
| 149 | void *to; /* current place in the buffer */ | ||
| 150 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 151 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 152 | void *farg; /* to make flush a closure */ | ||
| 153 | int nfmt; /* num chars formatted so far */ | ||
| 154 | va_list args; /* args passed to dofmt */ | ||
| 155 | int r; /* % format Rune */ | ||
| 156 | int width; | ||
| 157 | int prec; | ||
| 158 | ulong flags; | ||
| 159 | }; | ||
| 160 | |||
| 161 | enum{ | ||
| 162 | FmtWidth = 1, | ||
| 163 | FmtLeft = FmtWidth << 1, | ||
| 164 | FmtPrec = FmtLeft << 1, | ||
| 165 | FmtSharp = FmtPrec << 1, | ||
| 166 | FmtSpace = FmtSharp << 1, | ||
| 167 | FmtSign = FmtSpace << 1, | ||
| 168 | FmtZero = FmtSign << 1, | ||
| 169 | FmtUnsigned = FmtZero << 1, | ||
| 170 | FmtShort = FmtUnsigned << 1, | ||
| 171 | FmtLong = FmtShort << 1, | ||
| 172 | FmtVLong = FmtLong << 1, | ||
| 173 | FmtComma = FmtVLong << 1, | ||
| 174 | FmtByte = FmtComma << 1, | ||
| 175 | |||
| 176 | FmtFlag = FmtByte << 1 | ||
| 177 | }; | ||
| 178 | |||
| 179 | extern int print(char*, ...); | ||
| 180 | extern char* seprint(char*, char*, char*, ...); | ||
| 181 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 182 | extern int snprint(char*, int, char*, ...); | ||
| 183 | extern int vsnprint(char*, int, char*, va_list); | ||
| 184 | extern char* smprint(char*, ...); | ||
| 185 | extern char* vsmprint(char*, va_list); | ||
| 186 | extern int sprint(char*, char*, ...); | ||
| 187 | extern int fprint(int, char*, ...); | ||
| 188 | extern int vfprint(int, char*, va_list); | ||
| 189 | |||
| 190 | extern int runesprint(Rune*, char*, ...); | ||
| 191 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 192 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 193 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 194 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 195 | extern Rune* runesmprint(char*, ...); | ||
| 196 | extern Rune* runevsmprint(char*, va_list); | ||
| 197 | |||
| 198 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 199 | extern int fmtfdflush(Fmt*); | ||
| 200 | extern int fmtstrinit(Fmt*); | ||
| 201 | extern char* fmtstrflush(Fmt*); | ||
| 202 | extern int runefmtstrinit(Fmt*); | ||
| 203 | extern Rune* runefmtstrflush(Fmt*); | ||
| 204 | |||
| 205 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 206 | extern int dofmt(Fmt*, char*); | ||
| 207 | extern int dorfmt(Fmt*, Rune*); | ||
| 208 | extern int fmtprint(Fmt*, char*, ...); | ||
| 209 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 210 | extern int fmtrune(Fmt*, int); | ||
| 211 | extern int fmtstrcpy(Fmt*, char*); | ||
| 212 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 213 | /* | ||
| 214 | * error string for %r | ||
| 215 | * supplied on per os basis, not part of fmt library | ||
| 216 | */ | ||
| 217 | extern int errfmt(Fmt *f); | ||
| 218 | |||
| 219 | /* | ||
| 220 | * quoted strings | ||
| 221 | */ | ||
| 222 | extern char *unquotestrdup(char*); | ||
| 223 | extern Rune *unquoterunestrdup(Rune*); | ||
| 224 | extern char *quotestrdup(char*); | ||
| 225 | extern Rune *quoterunestrdup(Rune*); | ||
| 226 | extern int quotestrfmt(Fmt*); | ||
| 227 | extern int quoterunestrfmt(Fmt*); | ||
| 228 | extern void quotefmtinstall(void); | ||
| 229 | extern int (*doquote)(int); | ||
| 230 | |||
| 231 | /* | ||
| 232 | * random number | ||
| 233 | */ | ||
| 234 | extern int nrand(int); | ||
| 235 | extern ulong truerand(void); | ||
| 236 | extern ulong ntruerand(ulong); | ||
| 237 | |||
| 238 | /* | ||
| 239 | * math | ||
| 240 | */ | ||
| 241 | extern int isNaN(double); | ||
| 242 | extern int isInf(double, int); | ||
| 243 | extern double pow(double, double); | ||
| 244 | |||
| 245 | /* | ||
| 246 | * Time-of-day | ||
| 247 | */ | ||
| 248 | |||
| 249 | typedef struct Tm Tm; | ||
| 250 | struct Tm { | ||
| 251 | int sec; | ||
| 252 | int min; | ||
| 253 | int hour; | ||
| 254 | int mday; | ||
| 255 | int mon; | ||
| 256 | int year; | ||
| 257 | int wday; | ||
| 258 | int yday; | ||
| 259 | char zone[4]; | ||
| 260 | int tzoff; | ||
| 261 | }; | ||
| 262 | extern vlong osnsec(void); | ||
| 263 | #define nsec osnsec | ||
| 264 | |||
| 265 | /* | ||
| 266 | * one-of-a-kind | ||
| 267 | */ | ||
| 268 | extern void _assert(char*); | ||
| 269 | extern double charstod(int(*)(void*), void*); | ||
| 270 | extern char* cleanname(char*); | ||
| 271 | extern double frexp(double, int*); | ||
| 272 | extern uintptr getcallerpc(void*); | ||
| 273 | extern int getfields(char*, char**, int, int, char*); | ||
| 274 | extern char* getuser(void); | ||
| 275 | extern char* getwd(char*, int); | ||
| 276 | extern double ipow10(int); | ||
| 277 | extern double ldexp(double, int); | ||
| 278 | extern double modf(double, double*); | ||
| 279 | #define pow10 infpow10 | ||
| 280 | extern double pow10(int); | ||
| 281 | extern vlong strtoll(const char*, char**, int); | ||
| 282 | #define qsort infqsort | ||
| 283 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 284 | extern uvlong strtoull(const char*, char**, int); | ||
| 285 | extern void sysfatal(char*, ...); | ||
| 286 | extern int dec64(uchar*, int, char*, int); | ||
| 287 | extern int enc64(char*, int, uchar*, int); | ||
| 288 | extern int dec32(uchar*, int, char*, int); | ||
| 289 | extern int enc32(char*, int, uchar*, int); | ||
| 290 | extern int dec16(uchar*, int, char*, int); | ||
| 291 | extern int enc16(char*, int, uchar*, int); | ||
| 292 | extern int encodefmt(Fmt*); | ||
| 293 | |||
| 294 | /* | ||
| 295 | * synchronization | ||
| 296 | */ | ||
| 297 | typedef | ||
| 298 | struct Lock { | ||
| 299 | int val; | ||
| 300 | int pid; | ||
| 301 | } Lock; | ||
| 302 | |||
| 303 | extern int _tas(int*); | ||
| 304 | |||
| 305 | extern void lock(Lock*); | ||
| 306 | extern void unlock(Lock*); | ||
| 307 | extern int canlock(Lock*); | ||
| 308 | |||
| 309 | typedef struct QLock QLock; | ||
| 310 | struct QLock | ||
| 311 | { | ||
| 312 | Lock use; /* to access Qlock structure */ | ||
| 313 | Proc *head; /* next process waiting for object */ | ||
| 314 | Proc *tail; /* last process waiting for object */ | ||
| 315 | int locked; /* flag */ | ||
| 316 | }; | ||
| 317 | |||
| 318 | extern void qlock(QLock*); | ||
| 319 | extern void qunlock(QLock*); | ||
| 320 | extern int canqlock(QLock*); | ||
| 321 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 322 | |||
| 323 | typedef | ||
| 324 | struct RWLock | ||
| 325 | { | ||
| 326 | Lock l; /* Lock modify lock */ | ||
| 327 | QLock x; /* Mutual exclusion lock */ | ||
| 328 | QLock k; /* Lock for waiting writers */ | ||
| 329 | int readers; /* Count of readers in lock */ | ||
| 330 | } RWLock; | ||
| 331 | |||
| 332 | extern int canrlock(RWLock*); | ||
| 333 | extern int canwlock(RWLock*); | ||
| 334 | extern void rlock(RWLock*); | ||
| 335 | extern void runlock(RWLock*); | ||
| 336 | extern void wlock(RWLock*); | ||
| 337 | extern void wunlock(RWLock*); | ||
| 338 | |||
| 339 | /* | ||
| 340 | * network dialing | ||
| 341 | */ | ||
| 342 | #define NETPATHLEN 40 | ||
| 343 | |||
| 344 | /* | ||
| 345 | * system calls | ||
| 346 | * | ||
| 347 | */ | ||
| 348 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 349 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 350 | #define ERRMAX 128 /* max length of error string */ | ||
| 351 | |||
| 352 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 353 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 354 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 355 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 356 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 357 | #define MCACHE 0x0010 /* cache some data */ | ||
| 358 | #define MMASK 0x0017 /* all bits on */ | ||
| 359 | |||
| 360 | #define OREAD 0 /* open for read */ | ||
| 361 | #define OWRITE 1 /* write */ | ||
| 362 | #define ORDWR 2 /* read and write */ | ||
| 363 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 364 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 365 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 366 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 367 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 368 | |||
| 369 | #define AEXIST 0 /* accessible: exists */ | ||
| 370 | #define AEXEC 1 /* execute access */ | ||
| 371 | #define AWRITE 2 /* write access */ | ||
| 372 | #define AREAD 4 /* read access */ | ||
| 373 | |||
| 374 | /* bits in Qid.type */ | ||
| 375 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 376 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 377 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 378 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 379 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 380 | #define QTFILE 0x00 /* plain file */ | ||
| 381 | |||
| 382 | /* bits in Dir.mode */ | ||
| 383 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 384 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 385 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 386 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 387 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 388 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 389 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 390 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 391 | |||
| 392 | typedef | ||
| 393 | struct Qid | ||
| 394 | { | ||
| 395 | uvlong path; | ||
| 396 | ulong vers; | ||
| 397 | uchar type; | ||
| 398 | } Qid; | ||
| 399 | |||
| 400 | typedef | ||
| 401 | struct Dir { | ||
| 402 | /* system-modified data */ | ||
| 403 | ushort type; /* server type */ | ||
| 404 | uint dev; /* server subtype */ | ||
| 405 | /* file data */ | ||
| 406 | Qid qid; /* unique id from server */ | ||
| 407 | ulong mode; /* permissions */ | ||
| 408 | ulong atime; /* last read time */ | ||
| 409 | ulong mtime; /* last write time */ | ||
| 410 | vlong length; /* file length */ | ||
| 411 | char *name; /* last element of path */ | ||
| 412 | char *uid; /* owner name */ | ||
| 413 | char *gid; /* group name */ | ||
| 414 | char *muid; /* last modifier name */ | ||
| 415 | } Dir; | ||
| 416 | |||
| 417 | extern Dir* dirstat(char*); | ||
| 418 | extern Dir* dirfstat(int); | ||
| 419 | extern int dirwstat(char*, Dir*); | ||
| 420 | extern int dirfwstat(int, Dir*); | ||
| 421 | extern long dirread(int, Dir**); | ||
| 422 | extern void nulldir(Dir*); | ||
| 423 | extern long dirreadall(int, Dir**); | ||
| 424 | |||
| 425 | typedef | ||
| 426 | struct Waitmsg | ||
| 427 | { | ||
| 428 | int pid; /* of loved one */ | ||
| 429 | ulong time[3]; /* of loved one & descendants */ | ||
| 430 | char *msg; | ||
| 431 | } Waitmsg; | ||
| 432 | |||
| 433 | extern void _exits(char*); | ||
| 434 | |||
| 435 | extern void exits(char*); | ||
| 436 | extern int create(char*, int, int); | ||
| 437 | extern int errstr(char*, uint); | ||
| 438 | |||
| 439 | extern void perror(const char*); | ||
| 440 | extern long readn(int, void*, long); | ||
| 441 | extern int remove(const char*); | ||
| 442 | extern void rerrstr(char*, uint); | ||
| 443 | extern vlong seek(int, vlong, int); | ||
| 444 | extern int segflush(void*, ulong); | ||
| 445 | extern void werrstr(char*, ...); | ||
| 446 | |||
| 447 | extern char *argv0; | ||
| 448 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 449 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 450 | argc--, argv++) {\ | ||
| 451 | char *_args, *_argt;\ | ||
| 452 | Rune _argc;\ | ||
| 453 | _args = &argv[0][1];\ | ||
| 454 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 455 | argc--; argv++; break;\ | ||
| 456 | }\ | ||
| 457 | _argc = 0;\ | ||
| 458 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 459 | switch(_argc) | ||
| 460 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 461 | #define ARGF() (_argt=_args, _args="",\ | ||
| 462 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 463 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 464 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 465 | |||
| 466 | #define ARGC() _argc | ||
| 467 | |||
| 468 | /* | ||
| 469 | * Extensions for Inferno to basic libc.h | ||
| 470 | */ | ||
| 471 | |||
| 472 | #define setbinmode() | ||
| 473 | |||
Binary file not shown.
| @@ -0,0 +1,22 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc** Xup; | ||
| 8 | #define up (*Xup) | ||
| 9 | |||
| 10 | typedef struct FPU FPU; | ||
| 11 | |||
| 12 | /* | ||
| 13 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 14 | */ | ||
| 15 | struct FPU | ||
| 16 | { | ||
| 17 | uchar env[28]; | ||
| 18 | }; | ||
| 19 | |||
| 20 | typedef jmp_buf osjmpbuf; | ||
| 21 | #define ossetjmp(buf) setjmp(buf) | ||
| 22 | |||
| @@ -0,0 +1,658 @@ | |||
| 1 | #include <u.h> | ||
| 2 | typedef unsigned long size_t; | ||
| 3 | |||
| 4 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 5 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 6 | #define assert(x) if(x){}else _assert("x") | ||
| 7 | |||
| 8 | /* | ||
| 9 | * mem routines | ||
| 10 | */ | ||
| 11 | extern void* memccpy(void*, void*, int, ulong); | ||
| 12 | extern void* memset(void*, int, ulong); | ||
| 13 | extern int memcmp(void*, void*, ulong); | ||
| 14 | extern void* memcpy(void*, void*, ulong); | ||
| 15 | extern void* memmove(void*, void*, ulong); | ||
| 16 | extern void* memchr(void*, int, ulong); | ||
| 17 | |||
| 18 | /* | ||
| 19 | * string routines | ||
| 20 | */ | ||
| 21 | extern char* strcat(char*, char*); | ||
| 22 | extern char* strchr(char*, int); | ||
| 23 | extern int strcmp(char*, char*); | ||
| 24 | extern char* strcpy(char*, char*); | ||
| 25 | extern char* strecpy(char*, char*, char*); | ||
| 26 | extern char* strdup(char*); | ||
| 27 | extern char* strncat(char*, char*, long); | ||
| 28 | extern char* strncpy(char*, char*, long); | ||
| 29 | extern int strncmp(char*, char*, long); | ||
| 30 | extern char* strpbrk(char*, char*); | ||
| 31 | extern char* strrchr(char*, int); | ||
| 32 | extern char* strtok(char*, char*); | ||
| 33 | extern long strlen(char*); | ||
| 34 | extern long strspn(char*, char*); | ||
| 35 | extern long strcspn(char*, char*); | ||
| 36 | extern char* strstr(char*, char*); | ||
| 37 | extern int cistrncmp(char*, char*, int); | ||
| 38 | extern int cistrcmp(char*, char*); | ||
| 39 | extern char* cistrstr(char*, char*); | ||
| 40 | extern int tokenize(char*, char**, int); | ||
| 41 | |||
| 42 | enum | ||
| 43 | { | ||
| 44 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 45 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 46 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 47 | Runeerror = 0x80, /* decoding error in UTF */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * rune routines | ||
| 52 | */ | ||
| 53 | extern int runetochar(char*, Rune*); | ||
| 54 | extern int chartorune(Rune*, char*); | ||
| 55 | extern int runelen(long); | ||
| 56 | extern int runenlen(Rune*, int); | ||
| 57 | extern int fullrune(char*, int); | ||
| 58 | extern int utflen(char*); | ||
| 59 | extern int utfnlen(char*, long); | ||
| 60 | extern char* utfrune(char*, long); | ||
| 61 | extern char* utfrrune(char*, long); | ||
| 62 | extern char* utfutf(char*, char*); | ||
| 63 | extern char* utfecpy(char*, char*, char*); | ||
| 64 | |||
| 65 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 66 | extern Rune* runestrchr(Rune*, Rune); | ||
| 67 | extern int runestrcmp(Rune*, Rune*); | ||
| 68 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 69 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 70 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 71 | extern Rune* runestrdup(Rune*); | ||
| 72 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 73 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 74 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 75 | extern long runestrlen(Rune*); | ||
| 76 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 77 | |||
| 78 | extern Rune tolowerrune(Rune); | ||
| 79 | extern Rune totitlerune(Rune); | ||
| 80 | extern Rune toupperrune(Rune); | ||
| 81 | extern int isalpharune(Rune); | ||
| 82 | extern int islowerrune(Rune); | ||
| 83 | extern int isspacerune(Rune); | ||
| 84 | extern int istitlerune(Rune); | ||
| 85 | extern int isupperrune(Rune); | ||
| 86 | |||
| 87 | /* | ||
| 88 | * malloc | ||
| 89 | */ | ||
| 90 | extern void* malloc(ulong); | ||
| 91 | extern void* mallocz(ulong, int); | ||
| 92 | extern void free(void*); | ||
| 93 | extern ulong msize(void*); | ||
| 94 | extern void* calloc(ulong, ulong); | ||
| 95 | extern void* realloc(void*, ulong); | ||
| 96 | extern void setmalloctag(void*, ulong); | ||
| 97 | extern void setrealloctag(void*, ulong); | ||
| 98 | extern ulong getmalloctag(void*); | ||
| 99 | extern ulong getrealloctag(void*); | ||
| 100 | extern void* malloctopoolblock(void*); | ||
| 101 | |||
| 102 | /* | ||
| 103 | * print routines | ||
| 104 | */ | ||
| 105 | typedef struct Fmt Fmt; | ||
| 106 | struct Fmt{ | ||
| 107 | uchar runes; /* output buffer is runes or chars? */ | ||
| 108 | void *start; /* of buffer */ | ||
| 109 | void *to; /* current place in the buffer */ | ||
| 110 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 111 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 112 | void *farg; /* to make flush a closure */ | ||
| 113 | int nfmt; /* num chars formatted so far */ | ||
| 114 | va_list args; /* args passed to dofmt */ | ||
| 115 | int r; /* % format Rune */ | ||
| 116 | int width; | ||
| 117 | int prec; | ||
| 118 | ulong flags; | ||
| 119 | }; | ||
| 120 | |||
| 121 | enum{ | ||
| 122 | FmtWidth = 1, | ||
| 123 | FmtLeft = FmtWidth << 1, | ||
| 124 | FmtPrec = FmtLeft << 1, | ||
| 125 | FmtSharp = FmtPrec << 1, | ||
| 126 | FmtSpace = FmtSharp << 1, | ||
| 127 | FmtSign = FmtSpace << 1, | ||
| 128 | FmtZero = FmtSign << 1, | ||
| 129 | FmtUnsigned = FmtZero << 1, | ||
| 130 | FmtShort = FmtUnsigned << 1, | ||
| 131 | FmtLong = FmtShort << 1, | ||
| 132 | FmtVLong = FmtLong << 1, | ||
| 133 | FmtComma = FmtVLong << 1, | ||
| 134 | FmtByte = FmtComma << 1, | ||
| 135 | |||
| 136 | FmtFlag = FmtByte << 1 | ||
| 137 | }; | ||
| 138 | |||
| 139 | extern int print(char*, ...); | ||
| 140 | extern char* seprint(char*, char*, char*, ...); | ||
| 141 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 142 | extern int snprint(char*, int, char*, ...); | ||
| 143 | extern int vsnprint(char*, int, char*, va_list); | ||
| 144 | extern char* smprint(char*, ...); | ||
| 145 | extern char* vsmprint(char*, va_list); | ||
| 146 | extern int sprint(char*, char*, ...); | ||
| 147 | extern int fprint(int, char*, ...); | ||
| 148 | extern int vfprint(int, char*, va_list); | ||
| 149 | |||
| 150 | extern int runesprint(Rune*, char*, ...); | ||
| 151 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 152 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 153 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 154 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 155 | extern Rune* runesmprint(char*, ...); | ||
| 156 | extern Rune* runevsmprint(char*, va_list); | ||
| 157 | |||
| 158 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 159 | extern int fmtfdflush(Fmt*); | ||
| 160 | extern int fmtstrinit(Fmt*); | ||
| 161 | extern char* fmtstrflush(Fmt*); | ||
| 162 | extern int runefmtstrinit(Fmt*); | ||
| 163 | extern Rune* runefmtstrflush(Fmt*); | ||
| 164 | |||
| 165 | #pragma varargck argpos fmtprint 2 | ||
| 166 | #pragma varargck argpos fprint 2 | ||
| 167 | #pragma varargck argpos print 1 | ||
| 168 | #pragma varargck argpos runeseprint 3 | ||
| 169 | #pragma varargck argpos runesmprint 1 | ||
| 170 | #pragma varargck argpos runesnprint 3 | ||
| 171 | #pragma varargck argpos runesprint 2 | ||
| 172 | #pragma varargck argpos seprint 3 | ||
| 173 | #pragma varargck argpos smprint 1 | ||
| 174 | #pragma varargck argpos snprint 3 | ||
| 175 | #pragma varargck argpos sprint 2 | ||
| 176 | #pragma varargck argpos vseprint 3 | ||
| 177 | #pragma varargck argpos vsnprint 3 | ||
| 178 | |||
| 179 | #pragma varargck type "lld" vlong | ||
| 180 | #pragma varargck type "llx" vlong | ||
| 181 | #pragma varargck type "lld" uvlong | ||
| 182 | #pragma varargck type "llx" uvlong | ||
| 183 | #pragma varargck type "ld" long | ||
| 184 | #pragma varargck type "lx" long | ||
| 185 | #pragma varargck type "ld" ulong | ||
| 186 | #pragma varargck type "lx" ulong | ||
| 187 | #pragma varargck type "d" int | ||
| 188 | #pragma varargck type "x" int | ||
| 189 | #pragma varargck type "c" int | ||
| 190 | #pragma varargck type "C" int | ||
| 191 | #pragma varargck type "d" uint | ||
| 192 | #pragma varargck type "x" uint | ||
| 193 | #pragma varargck type "c" uint | ||
| 194 | #pragma varargck type "C" uint | ||
| 195 | #pragma varargck type "f" double | ||
| 196 | #pragma varargck type "e" double | ||
| 197 | #pragma varargck type "g" double | ||
| 198 | #pragma varargck type "s" char* | ||
| 199 | #pragma varargck type "q" char* | ||
| 200 | #pragma varargck type "S" Rune* | ||
| 201 | #pragma varargck type "Q" Rune* | ||
| 202 | #pragma varargck type "r" void | ||
| 203 | #pragma varargck type "%" void | ||
| 204 | #pragma varargck type "n" int* | ||
| 205 | #pragma varargck type "p" void* | ||
| 206 | #pragma varargck flag ',' | ||
| 207 | #pragma varargck type "<" void* | ||
| 208 | #pragma varargck type "[" void* | ||
| 209 | #pragma varargck type "H" void* | ||
| 210 | |||
| 211 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 212 | extern int dofmt(Fmt*, char*); | ||
| 213 | extern int dorfmt(Fmt*, Rune*); | ||
| 214 | extern int fmtprint(Fmt*, char*, ...); | ||
| 215 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 216 | extern int fmtrune(Fmt*, int); | ||
| 217 | extern int fmtstrcpy(Fmt*, char*); | ||
| 218 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 219 | /* | ||
| 220 | * error string for %r | ||
| 221 | * supplied on per os basis, not part of fmt library | ||
| 222 | */ | ||
| 223 | extern int errfmt(Fmt *f); | ||
| 224 | |||
| 225 | /* | ||
| 226 | * quoted strings | ||
| 227 | */ | ||
| 228 | extern char *unquotestrdup(char*); | ||
| 229 | extern Rune *unquoterunestrdup(Rune*); | ||
| 230 | extern char *quotestrdup(char*); | ||
| 231 | extern Rune *quoterunestrdup(Rune*); | ||
| 232 | extern int quotestrfmt(Fmt*); | ||
| 233 | extern int quoterunestrfmt(Fmt*); | ||
| 234 | extern void quotefmtinstall(void); | ||
| 235 | extern int (*doquote)(int); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * random number | ||
| 239 | */ | ||
| 240 | extern void srand(long); | ||
| 241 | extern int rand(void); | ||
| 242 | extern int nrand(int); | ||
| 243 | extern long lrand(void); | ||
| 244 | extern long lnrand(long); | ||
| 245 | extern double frand(void); | ||
| 246 | extern ulong truerand(void); | ||
| 247 | extern ulong ntruerand(ulong); | ||
| 248 | |||
| 249 | /* | ||
| 250 | * math | ||
| 251 | */ | ||
| 252 | extern ulong getfcr(void); | ||
| 253 | extern void setfsr(ulong); | ||
| 254 | extern ulong getfsr(void); | ||
| 255 | extern void setfcr(ulong); | ||
| 256 | extern double NaN(void); | ||
| 257 | extern double Inf(int); | ||
| 258 | extern int isNaN(double); | ||
| 259 | extern int isInf(double, int); | ||
| 260 | |||
| 261 | extern double pow(double, double); | ||
| 262 | extern double atan2(double, double); | ||
| 263 | extern double fabs(double); | ||
| 264 | extern double atan(double); | ||
| 265 | extern double log(double); | ||
| 266 | extern double log10(double); | ||
| 267 | extern double exp(double); | ||
| 268 | extern double floor(double); | ||
| 269 | extern double ceil(double); | ||
| 270 | extern double hypot(double, double); | ||
| 271 | extern double sin(double); | ||
| 272 | extern double cos(double); | ||
| 273 | extern double tan(double); | ||
| 274 | extern double asin(double); | ||
| 275 | extern double acos(double); | ||
| 276 | extern double sinh(double); | ||
| 277 | extern double cosh(double); | ||
| 278 | extern double tanh(double); | ||
| 279 | extern double sqrt(double); | ||
| 280 | extern double fmod(double, double); | ||
| 281 | |||
| 282 | #define HUGE 3.4028234e38 | ||
| 283 | #define PIO2 1.570796326794896619231e0 | ||
| 284 | #define PI (PIO2+PIO2) | ||
| 285 | |||
| 286 | /* | ||
| 287 | * Time-of-day | ||
| 288 | */ | ||
| 289 | |||
| 290 | typedef | ||
| 291 | struct Tm | ||
| 292 | { | ||
| 293 | int sec; | ||
| 294 | int min; | ||
| 295 | int hour; | ||
| 296 | int mday; | ||
| 297 | int mon; | ||
| 298 | int year; | ||
| 299 | int wday; | ||
| 300 | int yday; | ||
| 301 | char zone[4]; | ||
| 302 | int tzoff; | ||
| 303 | } Tm; | ||
| 304 | |||
| 305 | extern Tm* gmtime(long); | ||
| 306 | extern Tm* localtime(long); | ||
| 307 | extern char* asctime(Tm*); | ||
| 308 | extern char* ctime(long); | ||
| 309 | extern double cputime(void); | ||
| 310 | extern long times(long*); | ||
| 311 | extern long tm2sec(Tm*); | ||
| 312 | extern vlong nsec(void); | ||
| 313 | |||
| 314 | /* | ||
| 315 | * one-of-a-kind | ||
| 316 | */ | ||
| 317 | enum | ||
| 318 | { | ||
| 319 | PNPROC = 1, | ||
| 320 | PNGROUP = 2, | ||
| 321 | }; | ||
| 322 | |||
| 323 | extern void _assert(char*); | ||
| 324 | extern int abs(int); | ||
| 325 | extern int atexit(void(*)(void)); | ||
| 326 | extern void atexitdont(void(*)(void)); | ||
| 327 | extern int atnotify(int(*)(void*, char*), int); | ||
| 328 | extern double atof(char*); | ||
| 329 | extern int atoi(char*); | ||
| 330 | extern long atol(char*); | ||
| 331 | extern double charstod(int(*)(void*), void*); | ||
| 332 | extern char* cleanname(char*); | ||
| 333 | extern int decrypt(void*, void*, int); | ||
| 334 | extern int encrypt(void*, void*, int); | ||
| 335 | extern int dec64(uchar*, int, char*, int); | ||
| 336 | extern int enc64(char*, int, uchar*, int); | ||
| 337 | extern int dec32(uchar*, int, char*, int); | ||
| 338 | extern int enc32(char*, int, uchar*, int); | ||
| 339 | extern int dec16(uchar*, int, char*, int); | ||
| 340 | extern int enc16(char*, int, uchar*, int); | ||
| 341 | extern int encodefmt(Fmt*); | ||
| 342 | extern void exits(char*); | ||
| 343 | extern double frexp(double, int*); | ||
| 344 | extern uintptr getcallerpc(void*); | ||
| 345 | extern char* getenv(char*); | ||
| 346 | extern int getfields(char*, char**, int, int, char*); | ||
| 347 | extern char* getuser(void); | ||
| 348 | extern char* getwd(char*, int); | ||
| 349 | extern int iounit(int); | ||
| 350 | extern long labs(long); | ||
| 351 | extern double ldexp(double, int); | ||
| 352 | extern void longjmp(jmp_buf, int); | ||
| 353 | extern char* mktemp(char*); | ||
| 354 | extern double modf(double, double*); | ||
| 355 | extern int netcrypt(void*, void*); | ||
| 356 | extern void notejmp(void*, jmp_buf, int); | ||
| 357 | extern void perror(char*); | ||
| 358 | extern int postnote(int, int, char *); | ||
| 359 | extern double pow10(int); | ||
| 360 | extern double ipow10(int); | ||
| 361 | extern int putenv(char*, char*); | ||
| 362 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 363 | extern void* sbrk(ulong); | ||
| 364 | extern int setjmp(jmp_buf); | ||
| 365 | extern double strtod(char*, char**); | ||
| 366 | extern long strtol(char*, char**, int); | ||
| 367 | extern ulong strtoul(char*, char**, int); | ||
| 368 | extern vlong strtoll(char*, char**, int); | ||
| 369 | extern uvlong strtoull(char*, char**, int); | ||
| 370 | extern void sysfatal(char*, ...); | ||
| 371 | #pragma varargck argpos sysfatal 1 | ||
| 372 | extern void syslog(int, char*, char*, ...); | ||
| 373 | #pragma varargck argpos syslog 3 | ||
| 374 | extern long time(long*); | ||
| 375 | extern int tolower(int); | ||
| 376 | extern int toupper(int); | ||
| 377 | |||
| 378 | /* | ||
| 379 | * synchronization | ||
| 380 | */ | ||
| 381 | typedef | ||
| 382 | struct Lock { | ||
| 383 | int val; | ||
| 384 | } Lock; | ||
| 385 | |||
| 386 | extern int _tas(int*); | ||
| 387 | |||
| 388 | extern void lock(Lock*); | ||
| 389 | extern void unlock(Lock*); | ||
| 390 | extern int canlock(Lock*); | ||
| 391 | |||
| 392 | typedef struct QLp QLp; | ||
| 393 | struct QLp | ||
| 394 | { | ||
| 395 | int inuse; | ||
| 396 | QLp *next; | ||
| 397 | char state; | ||
| 398 | }; | ||
| 399 | |||
| 400 | typedef | ||
| 401 | struct QLock | ||
| 402 | { | ||
| 403 | Lock lock; | ||
| 404 | int locked; | ||
| 405 | QLp *head; | ||
| 406 | QLp *tail; | ||
| 407 | } QLock; | ||
| 408 | |||
| 409 | extern void qlock(QLock*); | ||
| 410 | extern void qunlock(QLock*); | ||
| 411 | extern int canqlock(QLock*); | ||
| 412 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 413 | |||
| 414 | typedef | ||
| 415 | struct RWLock | ||
| 416 | { | ||
| 417 | Lock lock; | ||
| 418 | int readers; /* number of readers */ | ||
| 419 | int writer; /* number of writers */ | ||
| 420 | QLp *head; /* list of waiting processes */ | ||
| 421 | QLp *tail; | ||
| 422 | } RWLock; | ||
| 423 | |||
| 424 | extern int canrlock(RWLock*); | ||
| 425 | extern int canwlock(RWLock*); | ||
| 426 | extern void rlock(RWLock*); | ||
| 427 | extern void runlock(RWLock*); | ||
| 428 | extern void wlock(RWLock*); | ||
| 429 | extern void wunlock(RWLock*); | ||
| 430 | |||
| 431 | extern void** privalloc(void); | ||
| 432 | extern void privfree(void**); | ||
| 433 | |||
| 434 | /* | ||
| 435 | * network dialing | ||
| 436 | */ | ||
| 437 | #define NETPATHLEN 40 | ||
| 438 | extern int accept(int, char*); | ||
| 439 | extern int announce(char*, char*); | ||
| 440 | extern int dial(char*, char*, char*, int*); | ||
| 441 | extern void setnetmtpt(char*, int, char*); | ||
| 442 | extern int hangup(int); | ||
| 443 | extern int listen(char*, char*); | ||
| 444 | extern char* netmkaddr(char*, char*, char*); | ||
| 445 | extern int reject(int, char*, char*); | ||
| 446 | |||
| 447 | /* | ||
| 448 | * system calls | ||
| 449 | * | ||
| 450 | */ | ||
| 451 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 452 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 453 | #define ERRMAX 128 /* max length of error string */ | ||
| 454 | |||
| 455 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 456 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 457 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 458 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 459 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 460 | #define MCACHE 0x0010 /* cache some data */ | ||
| 461 | #define MMASK 0x0017 /* all bits on */ | ||
| 462 | |||
| 463 | #define OREAD 0 /* open for read */ | ||
| 464 | #define OWRITE 1 /* write */ | ||
| 465 | #define ORDWR 2 /* read and write */ | ||
| 466 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 467 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 468 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 469 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 470 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 471 | |||
| 472 | #define AEXIST 0 /* accessible: exists */ | ||
| 473 | #define AEXEC 1 /* execute access */ | ||
| 474 | #define AWRITE 2 /* write access */ | ||
| 475 | #define AREAD 4 /* read access */ | ||
| 476 | |||
| 477 | |||
| 478 | /* Segattch */ | ||
| 479 | #define SG_RONLY 0040 /* read only */ | ||
| 480 | #define SG_CEXEC 0100 /* detach on exec */ | ||
| 481 | |||
| 482 | #define NCONT 0 /* continue after note */ | ||
| 483 | #define NDFLT 1 /* terminate after note */ | ||
| 484 | #define NSAVE 2 /* clear note but hold state */ | ||
| 485 | #define NRSTR 3 /* restore saved state */ | ||
| 486 | |||
| 487 | /* rfork */ | ||
| 488 | enum | ||
| 489 | { | ||
| 490 | RFNAMEG = (1<<0), | ||
| 491 | RFENVG = (1<<1), | ||
| 492 | RFFDG = (1<<2), | ||
| 493 | RFNOTEG = (1<<3), | ||
| 494 | RFPROC = (1<<4), | ||
| 495 | RFMEM = (1<<5), | ||
| 496 | RFNOWAIT = (1<<6), | ||
| 497 | RFCNAMEG = (1<<10), | ||
| 498 | RFCENVG = (1<<11), | ||
| 499 | RFCFDG = (1<<12), | ||
| 500 | RFREND = (1<<13), | ||
| 501 | RFNOMNT = (1<<14) | ||
| 502 | }; | ||
| 503 | |||
| 504 | /* bits in Qid.type */ | ||
| 505 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 506 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 507 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 508 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 509 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 510 | #define QTFILE 0x00 /* plain file */ | ||
| 511 | |||
| 512 | /* bits in Dir.mode */ | ||
| 513 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 514 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 515 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 516 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 517 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 518 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 519 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 520 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 521 | |||
| 522 | typedef | ||
| 523 | struct Qid | ||
| 524 | { | ||
| 525 | uvlong path; | ||
| 526 | ulong vers; | ||
| 527 | uchar type; | ||
| 528 | } Qid; | ||
| 529 | |||
| 530 | typedef | ||
| 531 | struct Dir { | ||
| 532 | /* system-modified data */ | ||
| 533 | ushort type; /* server type */ | ||
| 534 | uint dev; /* server subtype */ | ||
| 535 | /* file data */ | ||
| 536 | Qid qid; /* unique id from server */ | ||
| 537 | ulong mode; /* permissions */ | ||
| 538 | ulong atime; /* last read time */ | ||
| 539 | ulong mtime; /* last write time */ | ||
| 540 | vlong length; /* file length */ | ||
| 541 | char *name; /* last element of path */ | ||
| 542 | char *uid; /* owner name */ | ||
| 543 | char *gid; /* group name */ | ||
| 544 | char *muid; /* last modifier name */ | ||
| 545 | } Dir; | ||
| 546 | |||
| 547 | extern Dir* dirstat(char*); | ||
| 548 | extern Dir* dirfstat(int); | ||
| 549 | extern int dirwstat(char*, Dir*); | ||
| 550 | extern int dirfwstat(int, Dir*); | ||
| 551 | extern long dirread(int, Dir**); | ||
| 552 | extern void nulldir(Dir*); | ||
| 553 | extern long dirreadall(int, Dir**); | ||
| 554 | |||
| 555 | typedef | ||
| 556 | struct Waitmsg | ||
| 557 | { | ||
| 558 | int pid; /* of loved one */ | ||
| 559 | ulong time[3]; /* of loved one & descendants */ | ||
| 560 | char *msg; | ||
| 561 | } Waitmsg; | ||
| 562 | |||
| 563 | typedef | ||
| 564 | struct IOchunk | ||
| 565 | { | ||
| 566 | void *addr; | ||
| 567 | ulong len; | ||
| 568 | } IOchunk; | ||
| 569 | |||
| 570 | extern void _exits(char*); | ||
| 571 | |||
| 572 | extern void abort(void); | ||
| 573 | extern int access(char*, int); | ||
| 574 | extern long alarm(ulong); | ||
| 575 | extern int await(char*, int); | ||
| 576 | extern int bind(char*, char*, int); | ||
| 577 | extern int brk(void*); | ||
| 578 | extern int chdir(char*); | ||
| 579 | extern int close(int); | ||
| 580 | extern int create(char*, int, ulong); | ||
| 581 | extern int dup(int, int); | ||
| 582 | extern int errstr(char*, uint); | ||
| 583 | extern int exec(char*, char*[]); | ||
| 584 | extern int execl(char*, ...); | ||
| 585 | extern int fork(void); | ||
| 586 | extern int rfork(int); | ||
| 587 | extern int fauth(int, char*); | ||
| 588 | extern int fstat(int, uchar*, int); | ||
| 589 | extern int fwstat(int, uchar*, int); | ||
| 590 | extern int fversion(int, int, char*, int); | ||
| 591 | extern int mount(int, int, char*, int, char*); | ||
| 592 | extern int unmount(char*, char*); | ||
| 593 | extern int noted(int); | ||
| 594 | extern int notify(void(*)(void*, char*)); | ||
| 595 | extern int open(char*, int); | ||
| 596 | extern int fd2path(int, char*, int); | ||
| 597 | extern int pipe(int*); | ||
| 598 | extern long pread(int, void*, long, vlong); | ||
| 599 | extern long preadv(int, IOchunk*, int, vlong); | ||
| 600 | extern long pwrite(int, void*, long, vlong); | ||
| 601 | extern long pwritev(int, IOchunk*, int, vlong); | ||
| 602 | extern long read(int, void*, long); | ||
| 603 | extern long readn(int, void*, long); | ||
| 604 | extern long readv(int, IOchunk*, int); | ||
| 605 | extern int remove(char*); | ||
| 606 | extern void* sbrk(ulong); | ||
| 607 | extern long oseek(int, long, int); | ||
| 608 | extern vlong seek(int, vlong, int); | ||
| 609 | extern long segattach(int, char*, void*, ulong); | ||
| 610 | extern int segbrk(void*, void*); | ||
| 611 | extern int segdetach(void*); | ||
| 612 | extern int segflush(void*, ulong); | ||
| 613 | extern int segfree(void*, ulong); | ||
| 614 | extern int sleep(long); | ||
| 615 | extern int stat(char*, uchar*, int); | ||
| 616 | extern Waitmsg* wait(void); | ||
| 617 | extern int waitpid(void); | ||
| 618 | extern long write(int, void*, long); | ||
| 619 | extern long writev(int, IOchunk*, int); | ||
| 620 | extern int wstat(char*, uchar*, int); | ||
| 621 | extern void* rendezvous(void*, void*); | ||
| 622 | |||
| 623 | extern int getpid(void); | ||
| 624 | extern int getppid(void); | ||
| 625 | extern void rerrstr(char*, uint); | ||
| 626 | extern char* sysname(void); | ||
| 627 | extern void werrstr(char*, ...); | ||
| 628 | #pragma varargck argpos werrstr 1 | ||
| 629 | |||
| 630 | extern char *argv0; | ||
| 631 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 632 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 633 | argc--, argv++) {\ | ||
| 634 | char *_args, *_argt;\ | ||
| 635 | Rune _argc;\ | ||
| 636 | _args = &argv[0][1];\ | ||
| 637 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 638 | argc--; argv++; break;\ | ||
| 639 | }\ | ||
| 640 | _argc = 0;\ | ||
| 641 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 642 | switch(_argc) | ||
| 643 | #define ARGEND SET(_argt);USED(_argt,_argc,_args);}USED(argv, argc); | ||
| 644 | #define ARGF() (_argt=_args, _args="",\ | ||
| 645 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 646 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 647 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 648 | |||
| 649 | #define ARGC() _argc | ||
| 650 | |||
| 651 | |||
| 652 | /* | ||
| 653 | * Extensions for Inferno to basic libc.h | ||
| 654 | */ | ||
| 655 | |||
| 656 | #define setbinmode() | ||
| 657 | #define __LITTLE_ENDIAN | ||
| 658 | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | typedef unsigned short ushort; | ||
| 3 | typedef unsigned char uchar; | ||
| 4 | typedef unsigned long ulong; | ||
| 5 | typedef unsigned int uint; | ||
| 6 | typedef signed char schar; | ||
| 7 | typedef long long vlong; | ||
| 8 | typedef unsigned long long uvlong; | ||
| 9 | typedef unsigned long uintptr; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC 0 | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | |||
| 22 | /* FCR */ | ||
| 23 | #define FPINEX (1<<5) | ||
| 24 | #define FPUNFL ((1<<4)|(1<<1)) | ||
| 25 | #define FPOVFL (1<<3) | ||
| 26 | #define FPZDIV (1<<2) | ||
| 27 | #define FPINVAL (1<<0) | ||
| 28 | #define FPRNR (0<<10) | ||
| 29 | #define FPRZ (3<<10) | ||
| 30 | #define FPRPINF (2<<10) | ||
| 31 | #define FPRNINF (1<<10) | ||
| 32 | #define FPRMASK (3<<10) | ||
| 33 | #define FPPEXT (3<<8) | ||
| 34 | #define FPPSGL (0<<8) | ||
| 35 | #define FPPDBL (2<<8) | ||
| 36 | #define FPPMASK (3<<8) | ||
| 37 | /* FSR */ | ||
| 38 | #define FPAINEX FPINEX | ||
| 39 | #define FPAOVFL FPOVFL | ||
| 40 | #define FPAUNFL FPUNFL | ||
| 41 | #define FPAZDIV FPZDIV | ||
| 42 | #define FPAINVAL FPINVAL | ||
| 43 | union FPdbleword | ||
| 44 | { | ||
| 45 | double x; | ||
| 46 | struct { /* little endian */ | ||
| 47 | ulong lo; | ||
| 48 | ulong hi; | ||
| 49 | }; | ||
| 50 | }; | ||
| 51 | |||
| 52 | typedef char* va_list; | ||
| 53 | #define va_start(list, start) list =\ | ||
| 54 | (sizeof(start) < 4?\ | ||
| 55 | (char*)((int*)&(start)+1):\ | ||
| 56 | (char*)(&(start)+1)) | ||
| 57 | #define va_end(list)\ | ||
| 58 | USED(list) | ||
| 59 | #define va_arg(list, mode)\ | ||
| 60 | ((sizeof(mode) == 1)?\ | ||
| 61 | ((mode*)(list += 4))[-4]:\ | ||
| 62 | (sizeof(mode) == 2)?\ | ||
| 63 | ((mode*)(list += 4))[-2]:\ | ||
| 64 | ((mode*)(list += sizeof(mode)))[-1]) | ||
Empty file added.
| @@ -0,0 +1,22 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc** Xup; | ||
| 8 | #define up (*Xup) | ||
| 9 | |||
| 10 | typedef struct FPU FPU; | ||
| 11 | |||
| 12 | /* | ||
| 13 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 14 | */ | ||
| 15 | struct FPU | ||
| 16 | { | ||
| 17 | int dummy[1]; /* XXX what goes here? */ | ||
| 18 | }; | ||
| 19 | |||
| 20 | typedef jmp_buf osjmpbuf; | ||
| 21 | #define ossetjmp(buf) setjmp(buf) | ||
| 22 | |||
| @@ -0,0 +1,658 @@ | |||
| 1 | #include <u.h> | ||
| 2 | typedef unsigned long size_t; | ||
| 3 | |||
| 4 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 5 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 6 | #define assert(x) if(x){}else _assert("x") | ||
| 7 | |||
| 8 | /* | ||
| 9 | * mem routines | ||
| 10 | */ | ||
| 11 | extern void* memccpy(void*, void*, int, ulong); | ||
| 12 | extern void* memset(void*, int, ulong); | ||
| 13 | extern int memcmp(void*, void*, ulong); | ||
| 14 | extern void* memcpy(void*, void*, ulong); | ||
| 15 | extern void* memmove(void*, void*, ulong); | ||
| 16 | extern void* memchr(void*, int, ulong); | ||
| 17 | |||
| 18 | /* | ||
| 19 | * string routines | ||
| 20 | */ | ||
| 21 | extern char* strcat(char*, char*); | ||
| 22 | extern char* strchr(char*, int); | ||
| 23 | extern int strcmp(char*, char*); | ||
| 24 | extern char* strcpy(char*, char*); | ||
| 25 | extern char* strecpy(char*, char*, char*); | ||
| 26 | extern char* strdup(char*); | ||
| 27 | extern char* strncat(char*, char*, long); | ||
| 28 | extern char* strncpy(char*, char*, long); | ||
| 29 | extern int strncmp(char*, char*, long); | ||
| 30 | extern char* strpbrk(char*, char*); | ||
| 31 | extern char* strrchr(char*, int); | ||
| 32 | extern char* strtok(char*, char*); | ||
| 33 | extern long strlen(char*); | ||
| 34 | extern long strspn(char*, char*); | ||
| 35 | extern long strcspn(char*, char*); | ||
| 36 | extern char* strstr(char*, char*); | ||
| 37 | extern int cistrncmp(char*, char*, int); | ||
| 38 | extern int cistrcmp(char*, char*); | ||
| 39 | extern char* cistrstr(char*, char*); | ||
| 40 | extern int tokenize(char*, char**, int); | ||
| 41 | |||
| 42 | enum | ||
| 43 | { | ||
| 44 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 45 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 46 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 47 | Runeerror = 0x80, /* decoding error in UTF */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * rune routines | ||
| 52 | */ | ||
| 53 | extern int runetochar(char*, Rune*); | ||
| 54 | extern int chartorune(Rune*, char*); | ||
| 55 | extern int runelen(long); | ||
| 56 | extern int runenlen(Rune*, int); | ||
| 57 | extern int fullrune(char*, int); | ||
| 58 | extern int utflen(char*); | ||
| 59 | extern int utfnlen(char*, long); | ||
| 60 | extern char* utfrune(char*, long); | ||
| 61 | extern char* utfrrune(char*, long); | ||
| 62 | extern char* utfutf(char*, char*); | ||
| 63 | extern char* utfecpy(char*, char*, char*); | ||
| 64 | |||
| 65 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 66 | extern Rune* runestrchr(Rune*, Rune); | ||
| 67 | extern int runestrcmp(Rune*, Rune*); | ||
| 68 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 69 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 70 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 71 | extern Rune* runestrdup(Rune*); | ||
| 72 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 73 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 74 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 75 | extern long runestrlen(Rune*); | ||
| 76 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 77 | |||
| 78 | extern Rune tolowerrune(Rune); | ||
| 79 | extern Rune totitlerune(Rune); | ||
| 80 | extern Rune toupperrune(Rune); | ||
| 81 | extern int isalpharune(Rune); | ||
| 82 | extern int islowerrune(Rune); | ||
| 83 | extern int isspacerune(Rune); | ||
| 84 | extern int istitlerune(Rune); | ||
| 85 | extern int isupperrune(Rune); | ||
| 86 | |||
| 87 | /* | ||
| 88 | * malloc | ||
| 89 | */ | ||
| 90 | extern void* malloc(ulong); | ||
| 91 | extern void* mallocz(ulong, int); | ||
| 92 | extern void free(void*); | ||
| 93 | extern ulong msize(void*); | ||
| 94 | extern void* calloc(ulong, ulong); | ||
| 95 | extern void* realloc(void*, ulong); | ||
| 96 | extern void setmalloctag(void*, ulong); | ||
| 97 | extern void setrealloctag(void*, ulong); | ||
| 98 | extern ulong getmalloctag(void*); | ||
| 99 | extern ulong getrealloctag(void*); | ||
| 100 | extern void* malloctopoolblock(void*); | ||
| 101 | |||
| 102 | /* | ||
| 103 | * print routines | ||
| 104 | */ | ||
| 105 | typedef struct Fmt Fmt; | ||
| 106 | struct Fmt{ | ||
| 107 | uchar runes; /* output buffer is runes or chars? */ | ||
| 108 | void *start; /* of buffer */ | ||
| 109 | void *to; /* current place in the buffer */ | ||
| 110 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 111 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 112 | void *farg; /* to make flush a closure */ | ||
| 113 | int nfmt; /* num chars formatted so far */ | ||
| 114 | va_list args; /* args passed to dofmt */ | ||
| 115 | int r; /* % format Rune */ | ||
| 116 | int width; | ||
| 117 | int prec; | ||
| 118 | ulong flags; | ||
| 119 | }; | ||
| 120 | |||
| 121 | enum{ | ||
| 122 | FmtWidth = 1, | ||
| 123 | FmtLeft = FmtWidth << 1, | ||
| 124 | FmtPrec = FmtLeft << 1, | ||
| 125 | FmtSharp = FmtPrec << 1, | ||
| 126 | FmtSpace = FmtSharp << 1, | ||
| 127 | FmtSign = FmtSpace << 1, | ||
| 128 | FmtZero = FmtSign << 1, | ||
| 129 | FmtUnsigned = FmtZero << 1, | ||
| 130 | FmtShort = FmtUnsigned << 1, | ||
| 131 | FmtLong = FmtShort << 1, | ||
| 132 | FmtVLong = FmtLong << 1, | ||
| 133 | FmtComma = FmtVLong << 1, | ||
| 134 | FmtByte = FmtComma << 1, | ||
| 135 | |||
| 136 | FmtFlag = FmtByte << 1 | ||
| 137 | }; | ||
| 138 | |||
| 139 | extern int print(char*, ...); | ||
| 140 | extern char* seprint(char*, char*, char*, ...); | ||
| 141 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 142 | extern int snprint(char*, int, char*, ...); | ||
| 143 | extern int vsnprint(char*, int, char*, va_list); | ||
| 144 | extern char* smprint(char*, ...); | ||
| 145 | extern char* vsmprint(char*, va_list); | ||
| 146 | extern int sprint(char*, char*, ...); | ||
| 147 | extern int fprint(int, char*, ...); | ||
| 148 | extern int vfprint(int, char*, va_list); | ||
| 149 | |||
| 150 | extern int runesprint(Rune*, char*, ...); | ||
| 151 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 152 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 153 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 154 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 155 | extern Rune* runesmprint(char*, ...); | ||
| 156 | extern Rune* runevsmprint(char*, va_list); | ||
| 157 | |||
| 158 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 159 | extern int fmtfdflush(Fmt*); | ||
| 160 | extern int fmtstrinit(Fmt*); | ||
| 161 | extern char* fmtstrflush(Fmt*); | ||
| 162 | extern int runefmtstrinit(Fmt*); | ||
| 163 | extern Rune* runefmtstrflush(Fmt*); | ||
| 164 | |||
| 165 | #pragma varargck argpos fmtprint 2 | ||
| 166 | #pragma varargck argpos fprint 2 | ||
| 167 | #pragma varargck argpos print 1 | ||
| 168 | #pragma varargck argpos runeseprint 3 | ||
| 169 | #pragma varargck argpos runesmprint 1 | ||
| 170 | #pragma varargck argpos runesnprint 3 | ||
| 171 | #pragma varargck argpos runesprint 2 | ||
| 172 | #pragma varargck argpos seprint 3 | ||
| 173 | #pragma varargck argpos smprint 1 | ||
| 174 | #pragma varargck argpos snprint 3 | ||
| 175 | #pragma varargck argpos sprint 2 | ||
| 176 | #pragma varargck argpos vseprint 3 | ||
| 177 | #pragma varargck argpos vsnprint 3 | ||
| 178 | |||
| 179 | #pragma varargck type "lld" vlong | ||
| 180 | #pragma varargck type "llx" vlong | ||
| 181 | #pragma varargck type "lld" uvlong | ||
| 182 | #pragma varargck type "llx" uvlong | ||
| 183 | #pragma varargck type "ld" long | ||
| 184 | #pragma varargck type "lx" long | ||
| 185 | #pragma varargck type "ld" ulong | ||
| 186 | #pragma varargck type "lx" ulong | ||
| 187 | #pragma varargck type "d" int | ||
| 188 | #pragma varargck type "x" int | ||
| 189 | #pragma varargck type "c" int | ||
| 190 | #pragma varargck type "C" int | ||
| 191 | #pragma varargck type "d" uint | ||
| 192 | #pragma varargck type "x" uint | ||
| 193 | #pragma varargck type "c" uint | ||
| 194 | #pragma varargck type "C" uint | ||
| 195 | #pragma varargck type "f" double | ||
| 196 | #pragma varargck type "e" double | ||
| 197 | #pragma varargck type "g" double | ||
| 198 | #pragma varargck type "s" char* | ||
| 199 | #pragma varargck type "q" char* | ||
| 200 | #pragma varargck type "S" Rune* | ||
| 201 | #pragma varargck type "Q" Rune* | ||
| 202 | #pragma varargck type "r" void | ||
| 203 | #pragma varargck type "%" void | ||
| 204 | #pragma varargck type "n" int* | ||
| 205 | #pragma varargck type "p" void* | ||
| 206 | #pragma varargck flag ',' | ||
| 207 | #pragma varargck type "<" void* | ||
| 208 | #pragma varargck type "[" void* | ||
| 209 | #pragma varargck type "H" void* | ||
| 210 | |||
| 211 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 212 | extern int dofmt(Fmt*, char*); | ||
| 213 | extern int dorfmt(Fmt*, Rune*); | ||
| 214 | extern int fmtprint(Fmt*, char*, ...); | ||
| 215 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 216 | extern int fmtrune(Fmt*, int); | ||
| 217 | extern int fmtstrcpy(Fmt*, char*); | ||
| 218 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 219 | /* | ||
| 220 | * error string for %r | ||
| 221 | * supplied on per os basis, not part of fmt library | ||
| 222 | */ | ||
| 223 | extern int errfmt(Fmt *f); | ||
| 224 | |||
| 225 | /* | ||
| 226 | * quoted strings | ||
| 227 | */ | ||
| 228 | extern char *unquotestrdup(char*); | ||
| 229 | extern Rune *unquoterunestrdup(Rune*); | ||
| 230 | extern char *quotestrdup(char*); | ||
| 231 | extern Rune *quoterunestrdup(Rune*); | ||
| 232 | extern int quotestrfmt(Fmt*); | ||
| 233 | extern int quoterunestrfmt(Fmt*); | ||
| 234 | extern void quotefmtinstall(void); | ||
| 235 | extern int (*doquote)(int); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * random number | ||
| 239 | */ | ||
| 240 | extern void srand(long); | ||
| 241 | extern int rand(void); | ||
| 242 | extern int nrand(int); | ||
| 243 | extern long lrand(void); | ||
| 244 | extern long lnrand(long); | ||
| 245 | extern double frand(void); | ||
| 246 | extern ulong truerand(void); | ||
| 247 | extern ulong ntruerand(ulong); | ||
| 248 | |||
| 249 | /* | ||
| 250 | * math | ||
| 251 | */ | ||
| 252 | extern ulong getfcr(void); | ||
| 253 | extern void setfsr(ulong); | ||
| 254 | extern ulong getfsr(void); | ||
| 255 | extern void setfcr(ulong); | ||
| 256 | extern double NaN(void); | ||
| 257 | extern double Inf(int); | ||
| 258 | extern int isNaN(double); | ||
| 259 | extern int isInf(double, int); | ||
| 260 | |||
| 261 | extern double pow(double, double); | ||
| 262 | extern double atan2(double, double); | ||
| 263 | extern double fabs(double); | ||
| 264 | extern double atan(double); | ||
| 265 | extern double log(double); | ||
| 266 | extern double log10(double); | ||
| 267 | extern double exp(double); | ||
| 268 | extern double floor(double); | ||
| 269 | extern double ceil(double); | ||
| 270 | extern double hypot(double, double); | ||
| 271 | extern double sin(double); | ||
| 272 | extern double cos(double); | ||
| 273 | extern double tan(double); | ||
| 274 | extern double asin(double); | ||
| 275 | extern double acos(double); | ||
| 276 | extern double sinh(double); | ||
| 277 | extern double cosh(double); | ||
| 278 | extern double tanh(double); | ||
| 279 | extern double sqrt(double); | ||
| 280 | extern double fmod(double, double); | ||
| 281 | |||
| 282 | #define HUGE 3.4028234e38 | ||
| 283 | #define PIO2 1.570796326794896619231e0 | ||
| 284 | #define PI (PIO2+PIO2) | ||
| 285 | |||
| 286 | /* | ||
| 287 | * Time-of-day | ||
| 288 | */ | ||
| 289 | |||
| 290 | typedef | ||
| 291 | struct Tm | ||
| 292 | { | ||
| 293 | int sec; | ||
| 294 | int min; | ||
| 295 | int hour; | ||
| 296 | int mday; | ||
| 297 | int mon; | ||
| 298 | int year; | ||
| 299 | int wday; | ||
| 300 | int yday; | ||
| 301 | char zone[4]; | ||
| 302 | int tzoff; | ||
| 303 | } Tm; | ||
| 304 | |||
| 305 | extern Tm* gmtime(long); | ||
| 306 | extern Tm* localtime(long); | ||
| 307 | extern char* asctime(Tm*); | ||
| 308 | extern char* ctime(long); | ||
| 309 | extern double cputime(void); | ||
| 310 | extern long times(long*); | ||
| 311 | extern long tm2sec(Tm*); | ||
| 312 | extern vlong nsec(void); | ||
| 313 | |||
| 314 | /* | ||
| 315 | * one-of-a-kind | ||
| 316 | */ | ||
| 317 | enum | ||
| 318 | { | ||
| 319 | PNPROC = 1, | ||
| 320 | PNGROUP = 2, | ||
| 321 | }; | ||
| 322 | |||
| 323 | extern void _assert(char*); | ||
| 324 | extern int abs(int); | ||
| 325 | extern int atexit(void(*)(void)); | ||
| 326 | extern void atexitdont(void(*)(void)); | ||
| 327 | extern int atnotify(int(*)(void*, char*), int); | ||
| 328 | extern double atof(char*); | ||
| 329 | extern int atoi(char*); | ||
| 330 | extern long atol(char*); | ||
| 331 | extern double charstod(int(*)(void*), void*); | ||
| 332 | extern char* cleanname(char*); | ||
| 333 | extern int decrypt(void*, void*, int); | ||
| 334 | extern int encrypt(void*, void*, int); | ||
| 335 | extern int dec64(uchar*, int, char*, int); | ||
| 336 | extern int enc64(char*, int, uchar*, int); | ||
| 337 | extern int dec32(uchar*, int, char*, int); | ||
| 338 | extern int enc32(char*, int, uchar*, int); | ||
| 339 | extern int dec16(uchar*, int, char*, int); | ||
| 340 | extern int enc16(char*, int, uchar*, int); | ||
| 341 | extern int encodefmt(Fmt*); | ||
| 342 | extern void exits(char*); | ||
| 343 | extern double frexp(double, int*); | ||
| 344 | extern uintptr getcallerpc(void*); | ||
| 345 | extern char* getenv(char*); | ||
| 346 | extern int getfields(char*, char**, int, int, char*); | ||
| 347 | extern char* getuser(void); | ||
| 348 | extern char* getwd(char*, int); | ||
| 349 | extern int iounit(int); | ||
| 350 | extern long labs(long); | ||
| 351 | extern double ldexp(double, int); | ||
| 352 | extern void longjmp(jmp_buf, int); | ||
| 353 | extern char* mktemp(char*); | ||
| 354 | extern double modf(double, double*); | ||
| 355 | extern int netcrypt(void*, void*); | ||
| 356 | extern void notejmp(void*, jmp_buf, int); | ||
| 357 | extern void perror(char*); | ||
| 358 | extern int postnote(int, int, char *); | ||
| 359 | extern double pow10(int); | ||
| 360 | extern double ipow10(int); | ||
| 361 | extern int putenv(char*, char*); | ||
| 362 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 363 | extern void* sbrk(ulong); | ||
| 364 | extern int setjmp(jmp_buf); | ||
| 365 | extern double strtod(char*, char**); | ||
| 366 | extern long strtol(char*, char**, int); | ||
| 367 | extern ulong strtoul(char*, char**, int); | ||
| 368 | extern vlong strtoll(char*, char**, int); | ||
| 369 | extern uvlong strtoull(char*, char**, int); | ||
| 370 | extern void sysfatal(char*, ...); | ||
| 371 | #pragma varargck argpos sysfatal 1 | ||
| 372 | extern void syslog(int, char*, char*, ...); | ||
| 373 | #pragma varargck argpos syslog 3 | ||
| 374 | extern long time(long*); | ||
| 375 | extern int tolower(int); | ||
| 376 | extern int toupper(int); | ||
| 377 | |||
| 378 | /* | ||
| 379 | * synchronization | ||
| 380 | */ | ||
| 381 | typedef | ||
| 382 | struct Lock { | ||
| 383 | int val; | ||
| 384 | } Lock; | ||
| 385 | |||
| 386 | extern int _tas(int*); | ||
| 387 | |||
| 388 | extern void lock(Lock*); | ||
| 389 | extern void unlock(Lock*); | ||
| 390 | extern int canlock(Lock*); | ||
| 391 | |||
| 392 | typedef struct QLp QLp; | ||
| 393 | struct QLp | ||
| 394 | { | ||
| 395 | int inuse; | ||
| 396 | QLp *next; | ||
| 397 | char state; | ||
| 398 | }; | ||
| 399 | |||
| 400 | typedef | ||
| 401 | struct QLock | ||
| 402 | { | ||
| 403 | Lock lock; | ||
| 404 | int locked; | ||
| 405 | QLp *head; | ||
| 406 | QLp *tail; | ||
| 407 | } QLock; | ||
| 408 | |||
| 409 | extern void qlock(QLock*); | ||
| 410 | extern void qunlock(QLock*); | ||
| 411 | extern int canqlock(QLock*); | ||
| 412 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 413 | |||
| 414 | typedef | ||
| 415 | struct RWLock | ||
| 416 | { | ||
| 417 | Lock lock; | ||
| 418 | int readers; /* number of readers */ | ||
| 419 | int writer; /* number of writers */ | ||
| 420 | QLp *head; /* list of waiting processes */ | ||
| 421 | QLp *tail; | ||
| 422 | } RWLock; | ||
| 423 | |||
| 424 | extern int canrlock(RWLock*); | ||
| 425 | extern int canwlock(RWLock*); | ||
| 426 | extern void rlock(RWLock*); | ||
| 427 | extern void runlock(RWLock*); | ||
| 428 | extern void wlock(RWLock*); | ||
| 429 | extern void wunlock(RWLock*); | ||
| 430 | |||
| 431 | extern void** privalloc(void); | ||
| 432 | extern void privfree(void**); | ||
| 433 | |||
| 434 | /* | ||
| 435 | * network dialing | ||
| 436 | */ | ||
| 437 | #define NETPATHLEN 40 | ||
| 438 | extern int accept(int, char*); | ||
| 439 | extern int announce(char*, char*); | ||
| 440 | extern int dial(char*, char*, char*, int*); | ||
| 441 | extern void setnetmtpt(char*, int, char*); | ||
| 442 | extern int hangup(int); | ||
| 443 | extern int listen(char*, char*); | ||
| 444 | extern char* netmkaddr(char*, char*, char*); | ||
| 445 | extern int reject(int, char*, char*); | ||
| 446 | |||
| 447 | /* | ||
| 448 | * system calls | ||
| 449 | * | ||
| 450 | */ | ||
| 451 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 452 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 453 | #define ERRMAX 128 /* max length of error string */ | ||
| 454 | |||
| 455 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 456 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 457 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 458 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 459 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 460 | #define MCACHE 0x0010 /* cache some data */ | ||
| 461 | #define MMASK 0x0017 /* all bits on */ | ||
| 462 | |||
| 463 | #define OREAD 0 /* open for read */ | ||
| 464 | #define OWRITE 1 /* write */ | ||
| 465 | #define ORDWR 2 /* read and write */ | ||
| 466 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 467 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 468 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 469 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 470 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 471 | |||
| 472 | #define AEXIST 0 /* accessible: exists */ | ||
| 473 | #define AEXEC 1 /* execute access */ | ||
| 474 | #define AWRITE 2 /* write access */ | ||
| 475 | #define AREAD 4 /* read access */ | ||
| 476 | |||
| 477 | |||
| 478 | /* Segattch */ | ||
| 479 | #define SG_RONLY 0040 /* read only */ | ||
| 480 | #define SG_CEXEC 0100 /* detach on exec */ | ||
| 481 | |||
| 482 | #define NCONT 0 /* continue after note */ | ||
| 483 | #define NDFLT 1 /* terminate after note */ | ||
| 484 | #define NSAVE 2 /* clear note but hold state */ | ||
| 485 | #define NRSTR 3 /* restore saved state */ | ||
| 486 | |||
| 487 | /* rfork */ | ||
| 488 | enum | ||
| 489 | { | ||
| 490 | RFNAMEG = (1<<0), | ||
| 491 | RFENVG = (1<<1), | ||
| 492 | RFFDG = (1<<2), | ||
| 493 | RFNOTEG = (1<<3), | ||
| 494 | RFPROC = (1<<4), | ||
| 495 | RFMEM = (1<<5), | ||
| 496 | RFNOWAIT = (1<<6), | ||
| 497 | RFCNAMEG = (1<<10), | ||
| 498 | RFCENVG = (1<<11), | ||
| 499 | RFCFDG = (1<<12), | ||
| 500 | RFREND = (1<<13), | ||
| 501 | RFNOMNT = (1<<14) | ||
| 502 | }; | ||
| 503 | |||
| 504 | /* bits in Qid.type */ | ||
| 505 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 506 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 507 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 508 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 509 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 510 | #define QTFILE 0x00 /* plain file */ | ||
| 511 | |||
| 512 | /* bits in Dir.mode */ | ||
| 513 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 514 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 515 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 516 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 517 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 518 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 519 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 520 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 521 | |||
| 522 | typedef | ||
| 523 | struct Qid | ||
| 524 | { | ||
| 525 | uvlong path; | ||
| 526 | ulong vers; | ||
| 527 | uchar type; | ||
| 528 | } Qid; | ||
| 529 | |||
| 530 | typedef | ||
| 531 | struct Dir { | ||
| 532 | /* system-modified data */ | ||
| 533 | ushort type; /* server type */ | ||
| 534 | uint dev; /* server subtype */ | ||
| 535 | /* file data */ | ||
| 536 | Qid qid; /* unique id from server */ | ||
| 537 | ulong mode; /* permissions */ | ||
| 538 | ulong atime; /* last read time */ | ||
| 539 | ulong mtime; /* last write time */ | ||
| 540 | vlong length; /* file length */ | ||
| 541 | char *name; /* last element of path */ | ||
| 542 | char *uid; /* owner name */ | ||
| 543 | char *gid; /* group name */ | ||
| 544 | char *muid; /* last modifier name */ | ||
| 545 | } Dir; | ||
| 546 | |||
| 547 | extern Dir* dirstat(char*); | ||
| 548 | extern Dir* dirfstat(int); | ||
| 549 | extern int dirwstat(char*, Dir*); | ||
| 550 | extern int dirfwstat(int, Dir*); | ||
| 551 | extern long dirread(int, Dir**); | ||
| 552 | extern void nulldir(Dir*); | ||
| 553 | extern long dirreadall(int, Dir**); | ||
| 554 | |||
| 555 | typedef | ||
| 556 | struct Waitmsg | ||
| 557 | { | ||
| 558 | int pid; /* of loved one */ | ||
| 559 | ulong time[3]; /* of loved one & descendants */ | ||
| 560 | char *msg; | ||
| 561 | } Waitmsg; | ||
| 562 | |||
| 563 | typedef | ||
| 564 | struct IOchunk | ||
| 565 | { | ||
| 566 | void *addr; | ||
| 567 | ulong len; | ||
| 568 | } IOchunk; | ||
| 569 | |||
| 570 | extern void _exits(char*); | ||
| 571 | |||
| 572 | extern void abort(void); | ||
| 573 | extern int access(char*, int); | ||
| 574 | extern long alarm(ulong); | ||
| 575 | extern int await(char*, int); | ||
| 576 | extern int bind(char*, char*, int); | ||
| 577 | extern int brk(void*); | ||
| 578 | extern int chdir(char*); | ||
| 579 | extern int close(int); | ||
| 580 | extern int create(char*, int, ulong); | ||
| 581 | extern int dup(int, int); | ||
| 582 | extern int errstr(char*, uint); | ||
| 583 | extern int exec(char*, char*[]); | ||
| 584 | extern int execl(char*, ...); | ||
| 585 | extern int fork(void); | ||
| 586 | extern int rfork(int); | ||
| 587 | extern int fauth(int, char*); | ||
| 588 | extern int fstat(int, uchar*, int); | ||
| 589 | extern int fwstat(int, uchar*, int); | ||
| 590 | extern int fversion(int, int, char*, int); | ||
| 591 | extern int mount(int, int, char*, int, char*); | ||
| 592 | extern int unmount(char*, char*); | ||
| 593 | extern int noted(int); | ||
| 594 | extern int notify(void(*)(void*, char*)); | ||
| 595 | extern int open(char*, int); | ||
| 596 | extern int fd2path(int, char*, int); | ||
| 597 | extern int pipe(int*); | ||
| 598 | extern long pread(int, void*, long, vlong); | ||
| 599 | extern long preadv(int, IOchunk*, int, vlong); | ||
| 600 | extern long pwrite(int, void*, long, vlong); | ||
| 601 | extern long pwritev(int, IOchunk*, int, vlong); | ||
| 602 | extern long read(int, void*, long); | ||
| 603 | extern long readn(int, void*, long); | ||
| 604 | extern long readv(int, IOchunk*, int); | ||
| 605 | extern int remove(char*); | ||
| 606 | extern void* sbrk(ulong); | ||
| 607 | extern long oseek(int, long, int); | ||
| 608 | extern vlong seek(int, vlong, int); | ||
| 609 | extern long segattach(int, char*, void*, ulong); | ||
| 610 | extern int segbrk(void*, void*); | ||
| 611 | extern int segdetach(void*); | ||
| 612 | extern int segflush(void*, ulong); | ||
| 613 | extern int segfree(void*, ulong); | ||
| 614 | extern int sleep(long); | ||
| 615 | extern int stat(char*, uchar*, int); | ||
| 616 | extern Waitmsg* wait(void); | ||
| 617 | extern int waitpid(void); | ||
| 618 | extern long write(int, void*, long); | ||
| 619 | extern long writev(int, IOchunk*, int); | ||
| 620 | extern int wstat(char*, uchar*, int); | ||
| 621 | extern void* rendezvous(void*, void*); | ||
| 622 | |||
| 623 | extern int getpid(void); | ||
| 624 | extern int getppid(void); | ||
| 625 | extern void rerrstr(char*, uint); | ||
| 626 | extern char* sysname(void); | ||
| 627 | extern void werrstr(char*, ...); | ||
| 628 | #pragma varargck argpos werrstr 1 | ||
| 629 | |||
| 630 | extern char *argv0; | ||
| 631 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 632 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 633 | argc--, argv++) {\ | ||
| 634 | char *_args, *_argt;\ | ||
| 635 | Rune _argc;\ | ||
| 636 | _args = &argv[0][1];\ | ||
| 637 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 638 | argc--; argv++; break;\ | ||
| 639 | }\ | ||
| 640 | _argc = 0;\ | ||
| 641 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 642 | switch(_argc) | ||
| 643 | #define ARGEND SET(_argt);USED(_argt,_argc,_args);}USED(argv, argc); | ||
| 644 | #define ARGF() (_argt=_args, _args="",\ | ||
| 645 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 646 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 647 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 648 | |||
| 649 | #define ARGC() _argc | ||
| 650 | |||
| 651 | |||
| 652 | /* | ||
| 653 | * Extensions for Inferno to basic libc.h | ||
| 654 | */ | ||
| 655 | |||
| 656 | #define setbinmode() | ||
| 657 | #define __LITTLE_ENDIAN | ||
| 658 | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | |||
| 3 | typedef unsigned short ushort; | ||
| 4 | typedef unsigned char uchar; | ||
| 5 | typedef unsigned long ulong; | ||
| 6 | typedef unsigned int uint; | ||
| 7 | typedef signed char schar; | ||
| 8 | typedef long long vlong; | ||
| 9 | typedef unsigned long long uvlong; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC 0 | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | typedef unsigned long uintptr; | ||
| 22 | |||
| 23 | /* FCR */ | ||
| 24 | #define FPINEX (1<<20) | ||
| 25 | #define FPUNFL (1<<19) | ||
| 26 | #define FPOVFL (1<<18) | ||
| 27 | #define FPZDIV (1<<17) | ||
| 28 | #define FPINVAL (1<<16) | ||
| 29 | #define FPRNR (0<<0) | ||
| 30 | #define FPRZ (1<<0) | ||
| 31 | #define FPRPINF (2<<0) | ||
| 32 | #define FPRNINF (3<<0) | ||
| 33 | #define FPRMASK (3<<0) | ||
| 34 | #define FPPEXT 0 | ||
| 35 | #define FPPSGL 0 | ||
| 36 | #define FPPDBL 0 | ||
| 37 | #define FPPMASK 0 | ||
| 38 | /* FSR */ | ||
| 39 | #define FPAINEX (1<<4) | ||
| 40 | #define FPAUNFL (1<<3) | ||
| 41 | #define FPAOVFL (1<<2) | ||
| 42 | #define FPAZDIV (1<<1) | ||
| 43 | #define FPAINVAL (1<<0) | ||
| 44 | union FPdbleword | ||
| 45 | { | ||
| 46 | double x; | ||
| 47 | struct { /* little endian (on VFP and now in software) */ | ||
| 48 | ulong lo; | ||
| 49 | ulong hi; | ||
| 50 | }; | ||
| 51 | }; | ||
| 52 | |||
| 53 | typedef char* va_list; | ||
| 54 | #define va_start(list, start) list =\ | ||
| 55 | (sizeof(start) < 4?\ | ||
| 56 | (char*)((int*)&(start)+1):\ | ||
| 57 | (char*)(&(start)+1)) | ||
| 58 | #define va_end(list)\ | ||
| 59 | USED(list) | ||
| 60 | #define va_arg(list, mode)\ | ||
| 61 | ((sizeof(mode) == 1)?\ | ||
| 62 | ((mode*)(list += 4))[-4]:\ | ||
| 63 | (sizeof(mode) == 2)?\ | ||
| 64 | ((mode*)(list += 4))[-2]:\ | ||
| 65 | ((mode*)(list += sizeof(mode)))[-1]) | ||
Empty file added.
| @@ -0,0 +1,20 @@ | |||
| 1 | #include <u.h> | ||
| 2 | typedef usize size_t; | ||
| 3 | |||
| 4 | #define Runeerror xRuneerror | ||
| 5 | #define Rendez xRendez | ||
| 6 | #include <libc.h> | ||
| 7 | #undef Runeerror | ||
| 8 | #undef Rendez | ||
| 9 | |||
| 10 | |||
| 11 | enum | ||
| 12 | { | ||
| 13 | Runeerror = 0x80, /* decoding error in UTF */ | ||
| 14 | }; | ||
| 15 | /* | ||
| 16 | * Extensions for Inferno to basic libc.h | ||
| 17 | */ | ||
| 18 | |||
| 19 | #define setbinmode() | ||
| 20 | #define USE_FPdbleword | ||
| @@ -0,0 +1,20 @@ | |||
| 1 | #include <u.h> | ||
| 2 | typedef usize size_t; | ||
| 3 | |||
| 4 | #define Runeerror xRuneerror | ||
| 5 | #define Rendez xRendez | ||
| 6 | #include <libc.h> | ||
| 7 | #undef Runeerror | ||
| 8 | #undef Rendez | ||
| 9 | |||
| 10 | |||
| 11 | enum | ||
| 12 | { | ||
| 13 | Runeerror = 0x80, /* decoding error in UTF */ | ||
| 14 | }; | ||
| 15 | /* | ||
| 16 | * Extensions for Inferno to basic libc.h | ||
| 17 | */ | ||
| 18 | |||
| 19 | #define setbinmode() | ||
| 20 | #define USE_FPdbleword | ||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc** Xup; | ||
| 8 | #define up (*Xup) | ||
| 9 | |||
| 10 | typedef struct FPU FPU; | ||
| 11 | |||
| 12 | |||
| 13 | /* | ||
| 14 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 15 | */ | ||
| 16 | struct FPU | ||
| 17 | { | ||
| 18 | uchar env[28]; | ||
| 19 | }; | ||
| 20 | |||
| 21 | typedef jmp_buf osjmpbuf; | ||
| 22 | #define ossetjmp(buf) setjmp(buf) | ||
| 23 | |||
| @@ -0,0 +1,657 @@ | |||
| 1 | #include <u.h> | ||
| 2 | typedef unsigned long size_t; | ||
| 3 | |||
| 4 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 5 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 6 | #define assert(x) if(x){}else _assert("x") | ||
| 7 | |||
| 8 | /* | ||
| 9 | * mem routines | ||
| 10 | */ | ||
| 11 | extern void* memccpy(void*, void*, int, ulong); | ||
| 12 | extern void* memset(void*, int, ulong); | ||
| 13 | extern int memcmp(void*, void*, ulong); | ||
| 14 | extern void* memcpy(void*, void*, ulong); | ||
| 15 | extern void* memmove(void*, void*, ulong); | ||
| 16 | extern void* memchr(void*, int, ulong); | ||
| 17 | |||
| 18 | /* | ||
| 19 | * string routines | ||
| 20 | */ | ||
| 21 | extern char* strcat(char*, char*); | ||
| 22 | extern char* strchr(char*, int); | ||
| 23 | extern int strcmp(char*, char*); | ||
| 24 | extern char* strcpy(char*, char*); | ||
| 25 | extern char* strecpy(char*, char*, char*); | ||
| 26 | extern char* strdup(char*); | ||
| 27 | extern char* strncat(char*, char*, long); | ||
| 28 | extern char* strncpy(char*, char*, long); | ||
| 29 | extern int strncmp(char*, char*, long); | ||
| 30 | extern char* strpbrk(char*, char*); | ||
| 31 | extern char* strrchr(char*, int); | ||
| 32 | extern char* strtok(char*, char*); | ||
| 33 | extern long strlen(char*); | ||
| 34 | extern long strspn(char*, char*); | ||
| 35 | extern long strcspn(char*, char*); | ||
| 36 | extern char* strstr(char*, char*); | ||
| 37 | extern int cistrncmp(char*, char*, int); | ||
| 38 | extern int cistrcmp(char*, char*); | ||
| 39 | extern char* cistrstr(char*, char*); | ||
| 40 | extern int tokenize(char*, char**, int); | ||
| 41 | |||
| 42 | enum | ||
| 43 | { | ||
| 44 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 45 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 46 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 47 | Runeerror = 0x80, /* decoding error in UTF */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * rune routines | ||
| 52 | */ | ||
| 53 | extern int runetochar(char*, Rune*); | ||
| 54 | extern int chartorune(Rune*, char*); | ||
| 55 | extern int runelen(long); | ||
| 56 | extern int runenlen(Rune*, int); | ||
| 57 | extern int fullrune(char*, int); | ||
| 58 | extern int utflen(char*); | ||
| 59 | extern int utfnlen(char*, long); | ||
| 60 | extern char* utfrune(char*, long); | ||
| 61 | extern char* utfrrune(char*, long); | ||
| 62 | extern char* utfutf(char*, char*); | ||
| 63 | extern char* utfecpy(char*, char*, char*); | ||
| 64 | |||
| 65 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 66 | extern Rune* runestrchr(Rune*, Rune); | ||
| 67 | extern int runestrcmp(Rune*, Rune*); | ||
| 68 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 69 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 70 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 71 | extern Rune* runestrdup(Rune*); | ||
| 72 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 73 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 74 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 75 | extern long runestrlen(Rune*); | ||
| 76 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 77 | |||
| 78 | extern Rune tolowerrune(Rune); | ||
| 79 | extern Rune totitlerune(Rune); | ||
| 80 | extern Rune toupperrune(Rune); | ||
| 81 | extern int isalpharune(Rune); | ||
| 82 | extern int islowerrune(Rune); | ||
| 83 | extern int isspacerune(Rune); | ||
| 84 | extern int istitlerune(Rune); | ||
| 85 | extern int isupperrune(Rune); | ||
| 86 | |||
| 87 | /* | ||
| 88 | * malloc | ||
| 89 | */ | ||
| 90 | extern void* malloc(ulong); | ||
| 91 | extern void* mallocz(ulong, int); | ||
| 92 | extern void free(void*); | ||
| 93 | extern ulong msize(void*); | ||
| 94 | extern void* calloc(ulong, ulong); | ||
| 95 | extern void* realloc(void*, ulong); | ||
| 96 | extern void setmalloctag(void*, ulong); | ||
| 97 | extern void setrealloctag(void*, ulong); | ||
| 98 | extern ulong getmalloctag(void*); | ||
| 99 | extern ulong getrealloctag(void*); | ||
| 100 | extern void* malloctopoolblock(void*); | ||
| 101 | |||
| 102 | /* | ||
| 103 | * print routines | ||
| 104 | */ | ||
| 105 | typedef struct Fmt Fmt; | ||
| 106 | struct Fmt{ | ||
| 107 | uchar runes; /* output buffer is runes or chars? */ | ||
| 108 | void *start; /* of buffer */ | ||
| 109 | void *to; /* current place in the buffer */ | ||
| 110 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 111 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 112 | void *farg; /* to make flush a closure */ | ||
| 113 | int nfmt; /* num chars formatted so far */ | ||
| 114 | va_list args; /* args passed to dofmt */ | ||
| 115 | int r; /* % format Rune */ | ||
| 116 | int width; | ||
| 117 | int prec; | ||
| 118 | ulong flags; | ||
| 119 | }; | ||
| 120 | |||
| 121 | enum{ | ||
| 122 | FmtWidth = 1, | ||
| 123 | FmtLeft = FmtWidth << 1, | ||
| 124 | FmtPrec = FmtLeft << 1, | ||
| 125 | FmtSharp = FmtPrec << 1, | ||
| 126 | FmtSpace = FmtSharp << 1, | ||
| 127 | FmtSign = FmtSpace << 1, | ||
| 128 | FmtZero = FmtSign << 1, | ||
| 129 | FmtUnsigned = FmtZero << 1, | ||
| 130 | FmtShort = FmtUnsigned << 1, | ||
| 131 | FmtLong = FmtShort << 1, | ||
| 132 | FmtVLong = FmtLong << 1, | ||
| 133 | FmtComma = FmtVLong << 1, | ||
| 134 | FmtByte = FmtComma << 1, | ||
| 135 | |||
| 136 | FmtFlag = FmtByte << 1 | ||
| 137 | }; | ||
| 138 | |||
| 139 | extern int print(char*, ...); | ||
| 140 | extern char* seprint(char*, char*, char*, ...); | ||
| 141 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 142 | extern int snprint(char*, int, char*, ...); | ||
| 143 | extern int vsnprint(char*, int, char*, va_list); | ||
| 144 | extern char* smprint(char*, ...); | ||
| 145 | extern char* vsmprint(char*, va_list); | ||
| 146 | extern int sprint(char*, char*, ...); | ||
| 147 | extern int fprint(int, char*, ...); | ||
| 148 | extern int vfprint(int, char*, va_list); | ||
| 149 | |||
| 150 | extern int runesprint(Rune*, char*, ...); | ||
| 151 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 152 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 153 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 154 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 155 | extern Rune* runesmprint(char*, ...); | ||
| 156 | extern Rune* runevsmprint(char*, va_list); | ||
| 157 | |||
| 158 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 159 | extern int fmtfdflush(Fmt*); | ||
| 160 | extern int fmtstrinit(Fmt*); | ||
| 161 | extern char* fmtstrflush(Fmt*); | ||
| 162 | extern int runefmtstrinit(Fmt*); | ||
| 163 | extern Rune* runefmtstrflush(Fmt*); | ||
| 164 | |||
| 165 | #pragma varargck argpos fmtprint 2 | ||
| 166 | #pragma varargck argpos fprint 2 | ||
| 167 | #pragma varargck argpos print 1 | ||
| 168 | #pragma varargck argpos runeseprint 3 | ||
| 169 | #pragma varargck argpos runesmprint 1 | ||
| 170 | #pragma varargck argpos runesnprint 3 | ||
| 171 | #pragma varargck argpos runesprint 2 | ||
| 172 | #pragma varargck argpos seprint 3 | ||
| 173 | #pragma varargck argpos smprint 1 | ||
| 174 | #pragma varargck argpos snprint 3 | ||
| 175 | #pragma varargck argpos sprint 2 | ||
| 176 | #pragma varargck argpos vseprint 3 | ||
| 177 | #pragma varargck argpos vsnprint 3 | ||
| 178 | |||
| 179 | #pragma varargck type "lld" vlong | ||
| 180 | #pragma varargck type "llx" vlong | ||
| 181 | #pragma varargck type "lld" uvlong | ||
| 182 | #pragma varargck type "llx" uvlong | ||
| 183 | #pragma varargck type "ld" long | ||
| 184 | #pragma varargck type "lx" long | ||
| 185 | #pragma varargck type "ld" ulong | ||
| 186 | #pragma varargck type "lx" ulong | ||
| 187 | #pragma varargck type "d" int | ||
| 188 | #pragma varargck type "x" int | ||
| 189 | #pragma varargck type "c" int | ||
| 190 | #pragma varargck type "C" int | ||
| 191 | #pragma varargck type "d" uint | ||
| 192 | #pragma varargck type "x" uint | ||
| 193 | #pragma varargck type "c" uint | ||
| 194 | #pragma varargck type "C" uint | ||
| 195 | #pragma varargck type "f" double | ||
| 196 | #pragma varargck type "e" double | ||
| 197 | #pragma varargck type "g" double | ||
| 198 | #pragma varargck type "s" char* | ||
| 199 | #pragma varargck type "q" char* | ||
| 200 | #pragma varargck type "S" Rune* | ||
| 201 | #pragma varargck type "Q" Rune* | ||
| 202 | #pragma varargck type "r" void | ||
| 203 | #pragma varargck type "%" void | ||
| 204 | #pragma varargck type "n" int* | ||
| 205 | #pragma varargck type "p" void* | ||
| 206 | #pragma varargck flag ',' | ||
| 207 | #pragma varargck type "<" void* | ||
| 208 | #pragma varargck type "[" void* | ||
| 209 | #pragma varargck type "H" void* | ||
| 210 | |||
| 211 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 212 | extern int dofmt(Fmt*, char*); | ||
| 213 | extern int dorfmt(Fmt*, Rune*); | ||
| 214 | extern int fmtprint(Fmt*, char*, ...); | ||
| 215 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 216 | extern int fmtrune(Fmt*, int); | ||
| 217 | extern int fmtstrcpy(Fmt*, char*); | ||
| 218 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 219 | /* | ||
| 220 | * error string for %r | ||
| 221 | * supplied on per os basis, not part of fmt library | ||
| 222 | */ | ||
| 223 | extern int errfmt(Fmt *f); | ||
| 224 | |||
| 225 | /* | ||
| 226 | * quoted strings | ||
| 227 | */ | ||
| 228 | extern char *unquotestrdup(char*); | ||
| 229 | extern Rune *unquoterunestrdup(Rune*); | ||
| 230 | extern char *quotestrdup(char*); | ||
| 231 | extern Rune *quoterunestrdup(Rune*); | ||
| 232 | extern int quotestrfmt(Fmt*); | ||
| 233 | extern int quoterunestrfmt(Fmt*); | ||
| 234 | extern void quotefmtinstall(void); | ||
| 235 | extern int (*doquote)(int); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * random number | ||
| 239 | */ | ||
| 240 | extern void srand(long); | ||
| 241 | extern int rand(void); | ||
| 242 | extern int nrand(int); | ||
| 243 | extern long lrand(void); | ||
| 244 | extern long lnrand(long); | ||
| 245 | extern double frand(void); | ||
| 246 | extern ulong truerand(void); | ||
| 247 | extern ulong ntruerand(ulong); | ||
| 248 | |||
| 249 | /* | ||
| 250 | * math | ||
| 251 | */ | ||
| 252 | extern ulong getfcr(void); | ||
| 253 | extern void setfsr(ulong); | ||
| 254 | extern ulong getfsr(void); | ||
| 255 | extern void setfcr(ulong); | ||
| 256 | extern double NaN(void); | ||
| 257 | extern double Inf(int); | ||
| 258 | extern int isNaN(double); | ||
| 259 | extern int isInf(double, int); | ||
| 260 | |||
| 261 | extern double pow(double, double); | ||
| 262 | extern double atan2(double, double); | ||
| 263 | extern double fabs(double); | ||
| 264 | extern double atan(double); | ||
| 265 | extern double log(double); | ||
| 266 | extern double log10(double); | ||
| 267 | extern double exp(double); | ||
| 268 | extern double floor(double); | ||
| 269 | extern double ceil(double); | ||
| 270 | extern double hypot(double, double); | ||
| 271 | extern double sin(double); | ||
| 272 | extern double cos(double); | ||
| 273 | extern double tan(double); | ||
| 274 | extern double asin(double); | ||
| 275 | extern double acos(double); | ||
| 276 | extern double sinh(double); | ||
| 277 | extern double cosh(double); | ||
| 278 | extern double tanh(double); | ||
| 279 | extern double sqrt(double); | ||
| 280 | extern double fmod(double, double); | ||
| 281 | |||
| 282 | #define HUGE 3.4028234e38 | ||
| 283 | #define PIO2 1.570796326794896619231e0 | ||
| 284 | #define PI (PIO2+PIO2) | ||
| 285 | |||
| 286 | /* | ||
| 287 | * Time-of-day | ||
| 288 | */ | ||
| 289 | |||
| 290 | typedef | ||
| 291 | struct Tm | ||
| 292 | { | ||
| 293 | int sec; | ||
| 294 | int min; | ||
| 295 | int hour; | ||
| 296 | int mday; | ||
| 297 | int mon; | ||
| 298 | int year; | ||
| 299 | int wday; | ||
| 300 | int yday; | ||
| 301 | char zone[4]; | ||
| 302 | int tzoff; | ||
| 303 | } Tm; | ||
| 304 | |||
| 305 | extern Tm* gmtime(long); | ||
| 306 | extern Tm* localtime(long); | ||
| 307 | extern char* asctime(Tm*); | ||
| 308 | extern char* ctime(long); | ||
| 309 | extern double cputime(void); | ||
| 310 | extern long times(long*); | ||
| 311 | extern long tm2sec(Tm*); | ||
| 312 | extern vlong nsec(void); | ||
| 313 | |||
| 314 | /* | ||
| 315 | * one-of-a-kind | ||
| 316 | */ | ||
| 317 | enum | ||
| 318 | { | ||
| 319 | PNPROC = 1, | ||
| 320 | PNGROUP = 2, | ||
| 321 | }; | ||
| 322 | |||
| 323 | extern void _assert(char*); | ||
| 324 | extern int abs(int); | ||
| 325 | extern int atexit(void(*)(void)); | ||
| 326 | extern void atexitdont(void(*)(void)); | ||
| 327 | extern int atnotify(int(*)(void*, char*), int); | ||
| 328 | extern double atof(char*); | ||
| 329 | extern int atoi(char*); | ||
| 330 | extern long atol(char*); | ||
| 331 | extern double charstod(int(*)(void*), void*); | ||
| 332 | extern char* cleanname(char*); | ||
| 333 | extern int decrypt(void*, void*, int); | ||
| 334 | extern int encrypt(void*, void*, int); | ||
| 335 | extern int dec64(uchar*, int, char*, int); | ||
| 336 | extern int enc64(char*, int, uchar*, int); | ||
| 337 | extern int dec32(uchar*, int, char*, int); | ||
| 338 | extern int enc32(char*, int, uchar*, int); | ||
| 339 | extern int dec16(uchar*, int, char*, int); | ||
| 340 | extern int enc16(char*, int, uchar*, int); | ||
| 341 | extern int encodefmt(Fmt*); | ||
| 342 | extern void exits(char*); | ||
| 343 | extern double frexp(double, int*); | ||
| 344 | extern uintptr getcallerpc(void*); | ||
| 345 | extern char* getenv(char*); | ||
| 346 | extern int getfields(char*, char**, int, int, char*); | ||
| 347 | extern char* getuser(void); | ||
| 348 | extern char* getwd(char*, int); | ||
| 349 | extern int iounit(int); | ||
| 350 | extern long labs(long); | ||
| 351 | extern double ldexp(double, int); | ||
| 352 | extern void longjmp(jmp_buf, int); | ||
| 353 | extern char* mktemp(char*); | ||
| 354 | extern double modf(double, double*); | ||
| 355 | extern int netcrypt(void*, void*); | ||
| 356 | extern void notejmp(void*, jmp_buf, int); | ||
| 357 | extern void perror(char*); | ||
| 358 | extern int postnote(int, int, char *); | ||
| 359 | extern double pow10(int); | ||
| 360 | extern double ipow10(int); | ||
| 361 | extern int putenv(char*, char*); | ||
| 362 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 363 | extern void* sbrk(ulong); | ||
| 364 | extern int setjmp(jmp_buf); | ||
| 365 | extern double strtod(char*, char**); | ||
| 366 | extern long strtol(char*, char**, int); | ||
| 367 | extern ulong strtoul(char*, char**, int); | ||
| 368 | extern vlong strtoll(char*, char**, int); | ||
| 369 | extern uvlong strtoull(char*, char**, int); | ||
| 370 | extern void sysfatal(char*, ...); | ||
| 371 | #pragma varargck argpos sysfatal 1 | ||
| 372 | extern void syslog(int, char*, char*, ...); | ||
| 373 | #pragma varargck argpos syslog 3 | ||
| 374 | extern long time(long*); | ||
| 375 | extern int tolower(int); | ||
| 376 | extern int toupper(int); | ||
| 377 | |||
| 378 | /* | ||
| 379 | * synchronization | ||
| 380 | */ | ||
| 381 | typedef | ||
| 382 | struct Lock { | ||
| 383 | int val; | ||
| 384 | } Lock; | ||
| 385 | |||
| 386 | extern int _tas(int*); | ||
| 387 | |||
| 388 | extern void lock(Lock*); | ||
| 389 | extern void unlock(Lock*); | ||
| 390 | extern int canlock(Lock*); | ||
| 391 | |||
| 392 | typedef struct QLp QLp; | ||
| 393 | struct QLp | ||
| 394 | { | ||
| 395 | int inuse; | ||
| 396 | QLp *next; | ||
| 397 | char state; | ||
| 398 | }; | ||
| 399 | |||
| 400 | typedef | ||
| 401 | struct QLock | ||
| 402 | { | ||
| 403 | Lock lock; | ||
| 404 | int locked; | ||
| 405 | QLp *head; | ||
| 406 | QLp *tail; | ||
| 407 | } QLock; | ||
| 408 | |||
| 409 | extern void qlock(QLock*); | ||
| 410 | extern void qunlock(QLock*); | ||
| 411 | extern int canqlock(QLock*); | ||
| 412 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 413 | |||
| 414 | typedef | ||
| 415 | struct RWLock | ||
| 416 | { | ||
| 417 | Lock lock; | ||
| 418 | int readers; /* number of readers */ | ||
| 419 | int writer; /* number of writers */ | ||
| 420 | QLp *head; /* list of waiting processes */ | ||
| 421 | QLp *tail; | ||
| 422 | } RWLock; | ||
| 423 | |||
| 424 | extern int canrlock(RWLock*); | ||
| 425 | extern int canwlock(RWLock*); | ||
| 426 | extern void rlock(RWLock*); | ||
| 427 | extern void runlock(RWLock*); | ||
| 428 | extern void wlock(RWLock*); | ||
| 429 | extern void wunlock(RWLock*); | ||
| 430 | |||
| 431 | extern void** privalloc(void); | ||
| 432 | extern void privfree(void**); | ||
| 433 | |||
| 434 | /* | ||
| 435 | * network dialing | ||
| 436 | */ | ||
| 437 | #define NETPATHLEN 40 | ||
| 438 | extern int accept(int, char*); | ||
| 439 | extern int announce(char*, char*); | ||
| 440 | extern int dial(char*, char*, char*, int*); | ||
| 441 | extern void setnetmtpt(char*, int, char*); | ||
| 442 | extern int hangup(int); | ||
| 443 | extern int listen(char*, char*); | ||
| 444 | extern char* netmkaddr(char*, char*, char*); | ||
| 445 | extern int reject(int, char*, char*); | ||
| 446 | |||
| 447 | /* | ||
| 448 | * system calls | ||
| 449 | * | ||
| 450 | */ | ||
| 451 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 452 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 453 | #define ERRMAX 128 /* max length of error string */ | ||
| 454 | |||
| 455 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 456 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 457 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 458 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 459 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 460 | #define MCACHE 0x0010 /* cache some data */ | ||
| 461 | #define MMASK 0x0017 /* all bits on */ | ||
| 462 | |||
| 463 | #define OREAD 0 /* open for read */ | ||
| 464 | #define OWRITE 1 /* write */ | ||
| 465 | #define ORDWR 2 /* read and write */ | ||
| 466 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 467 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 468 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 469 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 470 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 471 | |||
| 472 | #define AEXIST 0 /* accessible: exists */ | ||
| 473 | #define AEXEC 1 /* execute access */ | ||
| 474 | #define AWRITE 2 /* write access */ | ||
| 475 | #define AREAD 4 /* read access */ | ||
| 476 | |||
| 477 | |||
| 478 | /* Segattch */ | ||
| 479 | #define SG_RONLY 0040 /* read only */ | ||
| 480 | #define SG_CEXEC 0100 /* detach on exec */ | ||
| 481 | |||
| 482 | #define NCONT 0 /* continue after note */ | ||
| 483 | #define NDFLT 1 /* terminate after note */ | ||
| 484 | #define NSAVE 2 /* clear note but hold state */ | ||
| 485 | #define NRSTR 3 /* restore saved state */ | ||
| 486 | |||
| 487 | /* rfork */ | ||
| 488 | enum | ||
| 489 | { | ||
| 490 | RFNAMEG = (1<<0), | ||
| 491 | RFENVG = (1<<1), | ||
| 492 | RFFDG = (1<<2), | ||
| 493 | RFNOTEG = (1<<3), | ||
| 494 | RFPROC = (1<<4), | ||
| 495 | RFMEM = (1<<5), | ||
| 496 | RFNOWAIT = (1<<6), | ||
| 497 | RFCNAMEG = (1<<10), | ||
| 498 | RFCENVG = (1<<11), | ||
| 499 | RFCFDG = (1<<12), | ||
| 500 | RFREND = (1<<13), | ||
| 501 | RFNOMNT = (1<<14) | ||
| 502 | }; | ||
| 503 | |||
| 504 | /* bits in Qid.type */ | ||
| 505 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 506 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 507 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 508 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 509 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 510 | #define QTFILE 0x00 /* plain file */ | ||
| 511 | |||
| 512 | /* bits in Dir.mode */ | ||
| 513 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 514 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 515 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 516 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 517 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 518 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 519 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 520 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 521 | |||
| 522 | typedef | ||
| 523 | struct Qid | ||
| 524 | { | ||
| 525 | uvlong path; | ||
| 526 | ulong vers; | ||
| 527 | uchar type; | ||
| 528 | } Qid; | ||
| 529 | |||
| 530 | typedef | ||
| 531 | struct Dir { | ||
| 532 | /* system-modified data */ | ||
| 533 | ushort type; /* server type */ | ||
| 534 | uint dev; /* server subtype */ | ||
| 535 | /* file data */ | ||
| 536 | Qid qid; /* unique id from server */ | ||
| 537 | ulong mode; /* permissions */ | ||
| 538 | ulong atime; /* last read time */ | ||
| 539 | ulong mtime; /* last write time */ | ||
| 540 | vlong length; /* file length */ | ||
| 541 | char *name; /* last element of path */ | ||
| 542 | char *uid; /* owner name */ | ||
| 543 | char *gid; /* group name */ | ||
| 544 | char *muid; /* last modifier name */ | ||
| 545 | } Dir; | ||
| 546 | |||
| 547 | extern Dir* dirstat(char*); | ||
| 548 | extern Dir* dirfstat(int); | ||
| 549 | extern int dirwstat(char*, Dir*); | ||
| 550 | extern int dirfwstat(int, Dir*); | ||
| 551 | extern long dirread(int, Dir**); | ||
| 552 | extern void nulldir(Dir*); | ||
| 553 | extern long dirreadall(int, Dir**); | ||
| 554 | |||
| 555 | typedef | ||
| 556 | struct Waitmsg | ||
| 557 | { | ||
| 558 | int pid; /* of loved one */ | ||
| 559 | ulong time[3]; /* of loved one & descendants */ | ||
| 560 | char *msg; | ||
| 561 | } Waitmsg; | ||
| 562 | |||
| 563 | typedef | ||
| 564 | struct IOchunk | ||
| 565 | { | ||
| 566 | void *addr; | ||
| 567 | ulong len; | ||
| 568 | } IOchunk; | ||
| 569 | |||
| 570 | extern void _exits(char*); | ||
| 571 | |||
| 572 | extern void abort(void); | ||
| 573 | extern int access(char*, int); | ||
| 574 | extern long alarm(ulong); | ||
| 575 | extern int await(char*, int); | ||
| 576 | extern int bind(char*, char*, int); | ||
| 577 | extern int brk(void*); | ||
| 578 | extern int chdir(char*); | ||
| 579 | extern int close(int); | ||
| 580 | extern int create(char*, int, ulong); | ||
| 581 | extern int dup(int, int); | ||
| 582 | extern int errstr(char*, uint); | ||
| 583 | extern int exec(char*, char*[]); | ||
| 584 | extern int execl(char*, ...); | ||
| 585 | extern int fork(void); | ||
| 586 | extern int rfork(int); | ||
| 587 | extern int fauth(int, char*); | ||
| 588 | extern int fstat(int, uchar*, int); | ||
| 589 | extern int fwstat(int, uchar*, int); | ||
| 590 | extern int fversion(int, int, char*, int); | ||
| 591 | extern int mount(int, int, char*, int, char*); | ||
| 592 | extern int unmount(char*, char*); | ||
| 593 | extern int noted(int); | ||
| 594 | extern int notify(void(*)(void*, char*)); | ||
| 595 | extern int open(char*, int); | ||
| 596 | extern int fd2path(int, char*, int); | ||
| 597 | extern int pipe(int*); | ||
| 598 | extern long pread(int, void*, long, vlong); | ||
| 599 | extern long preadv(int, IOchunk*, int, vlong); | ||
| 600 | extern long pwrite(int, void*, long, vlong); | ||
| 601 | extern long pwritev(int, IOchunk*, int, vlong); | ||
| 602 | extern long read(int, void*, long); | ||
| 603 | extern long readn(int, void*, long); | ||
| 604 | extern long readv(int, IOchunk*, int); | ||
| 605 | extern int remove(char*); | ||
| 606 | extern void* sbrk(ulong); | ||
| 607 | extern long oseek(int, long, int); | ||
| 608 | extern vlong seek(int, vlong, int); | ||
| 609 | extern long segattach(int, char*, void*, ulong); | ||
| 610 | extern int segbrk(void*, void*); | ||
| 611 | extern int segdetach(void*); | ||
| 612 | extern int segflush(void*, ulong); | ||
| 613 | extern int segfree(void*, ulong); | ||
| 614 | extern int sleep(long); | ||
| 615 | extern int stat(char*, uchar*, int); | ||
| 616 | extern Waitmsg* wait(void); | ||
| 617 | extern int waitpid(void); | ||
| 618 | extern long write(int, void*, long); | ||
| 619 | extern long writev(int, IOchunk*, int); | ||
| 620 | extern int wstat(char*, uchar*, int); | ||
| 621 | extern void* rendezvous(void*, void*); | ||
| 622 | |||
| 623 | extern int getpid(void); | ||
| 624 | extern int getppid(void); | ||
| 625 | extern void rerrstr(char*, uint); | ||
| 626 | extern char* sysname(void); | ||
| 627 | extern void werrstr(char*, ...); | ||
| 628 | #pragma varargck argpos werrstr 1 | ||
| 629 | |||
| 630 | extern char *argv0; | ||
| 631 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 632 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 633 | argc--, argv++) {\ | ||
| 634 | char *_args, *_argt;\ | ||
| 635 | Rune _argc;\ | ||
| 636 | _args = &argv[0][1];\ | ||
| 637 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 638 | argc--; argv++; break;\ | ||
| 639 | }\ | ||
| 640 | _argc = 0;\ | ||
| 641 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 642 | switch(_argc) | ||
| 643 | #define ARGEND SET(_argt);USED(_argt,_argc,_args);}USED(argv, argc); | ||
| 644 | #define ARGF() (_argt=_args, _args="",\ | ||
| 645 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 646 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 647 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 648 | |||
| 649 | #define ARGC() _argc | ||
| 650 | |||
| 651 | /* | ||
| 652 | * Extensions for Inferno to basic libc.h | ||
| 653 | */ | ||
| 654 | |||
| 655 | #define setbinmode() | ||
| 656 | #undef __LITTLE_ENDIAN | ||
| 657 | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | typedef unsigned short ushort; | ||
| 3 | typedef unsigned char uchar; | ||
| 4 | typedef unsigned long ulong; | ||
| 5 | typedef unsigned int uint; | ||
| 6 | typedef signed char schar; | ||
| 7 | typedef long long vlong; | ||
| 8 | typedef unsigned long long uvlong; | ||
| 9 | typedef unsigned long uintptr; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC 0 | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | |||
| 22 | /* FCR */ | ||
| 23 | #define FPINEX (1<<7) | ||
| 24 | #define FPUNFL (1<<8) | ||
| 25 | #define FPOVFL (1<<9) | ||
| 26 | #define FPZDIV (1<<10) | ||
| 27 | #define FPINVAL (1<<11) | ||
| 28 | #define FPRNR (0<<0) | ||
| 29 | #define FPRZ (1<<0) | ||
| 30 | #define FPRPINF (2<<0) | ||
| 31 | #define FPRNINF (3<<0) | ||
| 32 | #define FPRMASK (3<<0) | ||
| 33 | #define FPPEXT 0 | ||
| 34 | #define FPPSGL 0 | ||
| 35 | #define FPPDBL 0 | ||
| 36 | #define FPPMASK 0 | ||
| 37 | /* FSR */ | ||
| 38 | #define FPAINEX (1<<2) | ||
| 39 | #define FPAOVFL (1<<4) | ||
| 40 | #define FPAUNFL (1<<3) | ||
| 41 | #define FPAZDIV (1<<5) | ||
| 42 | #define FPAINVAL (1<<6) | ||
| 43 | union FPdbleword | ||
| 44 | { | ||
| 45 | double x; | ||
| 46 | struct { /* big endian */ | ||
| 47 | ulong hi; | ||
| 48 | ulong lo; | ||
| 49 | }; | ||
| 50 | }; | ||
| 51 | |||
| 52 | /* stdarg */ | ||
| 53 | typedef char* va_list; | ||
| 54 | #define va_start(list, start) list =\ | ||
| 55 | (sizeof(start) < 4?\ | ||
| 56 | (char*)((int*)&(start)+1):\ | ||
| 57 | (char*)(&(start)+1)) | ||
| 58 | #define va_end(list)\ | ||
| 59 | USED(list) | ||
| 60 | #define va_arg(list, mode)\ | ||
| 61 | ((sizeof(mode) == 1)?\ | ||
| 62 | ((mode*)(list += 4))[-1]:\ | ||
| 63 | (sizeof(mode) == 2)?\ | ||
| 64 | ((mode*)(list += 4))[-1]:\ | ||
| 65 | ((mode*)(list += sizeof(mode)))[-1]) | ||
| @@ -0,0 +1,30 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc** Xup; | ||
| 8 | #define up (*Xup) | ||
| 9 | |||
| 10 | typedef struct FPU FPU; | ||
| 11 | |||
| 12 | /* | ||
| 13 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 14 | */ | ||
| 15 | typedef struct FPU FPU; | ||
| 16 | struct FPU | ||
| 17 | { | ||
| 18 | double fpreg[32]; | ||
| 19 | union { | ||
| 20 | double fpscrd; | ||
| 21 | struct { | ||
| 22 | ulong pad; | ||
| 23 | ulong fpscr; | ||
| 24 | }; | ||
| 25 | }; | ||
| 26 | }; | ||
| 27 | |||
| 28 | typedef jmp_buf osjmpbuf; | ||
| 29 | #define ossetjmp(buf) setjmp(buf) | ||
| 30 | |||
| @@ -0,0 +1,657 @@ | |||
| 1 | #include <u.h> | ||
| 2 | typedef unsigned long size_t; | ||
| 3 | |||
| 4 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 5 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 6 | #define assert(x) if(x){}else _assert("x") | ||
| 7 | |||
| 8 | /* | ||
| 9 | * mem routines | ||
| 10 | */ | ||
| 11 | extern void* memccpy(void*, void*, int, ulong); | ||
| 12 | extern void* memset(void*, int, ulong); | ||
| 13 | extern int memcmp(void*, void*, ulong); | ||
| 14 | extern void* memcpy(void*, void*, ulong); | ||
| 15 | extern void* memmove(void*, void*, ulong); | ||
| 16 | extern void* memchr(void*, int, ulong); | ||
| 17 | |||
| 18 | /* | ||
| 19 | * string routines | ||
| 20 | */ | ||
| 21 | extern char* strcat(char*, char*); | ||
| 22 | extern char* strchr(char*, int); | ||
| 23 | extern int strcmp(char*, char*); | ||
| 24 | extern char* strcpy(char*, char*); | ||
| 25 | extern char* strecpy(char*, char*, char*); | ||
| 26 | extern char* strdup(char*); | ||
| 27 | extern char* strncat(char*, char*, long); | ||
| 28 | extern char* strncpy(char*, char*, long); | ||
| 29 | extern int strncmp(char*, char*, long); | ||
| 30 | extern char* strpbrk(char*, char*); | ||
| 31 | extern char* strrchr(char*, int); | ||
| 32 | extern char* strtok(char*, char*); | ||
| 33 | extern long strlen(char*); | ||
| 34 | extern long strspn(char*, char*); | ||
| 35 | extern long strcspn(char*, char*); | ||
| 36 | extern char* strstr(char*, char*); | ||
| 37 | extern int cistrncmp(char*, char*, int); | ||
| 38 | extern int cistrcmp(char*, char*); | ||
| 39 | extern char* cistrstr(char*, char*); | ||
| 40 | extern int tokenize(char*, char**, int); | ||
| 41 | |||
| 42 | enum | ||
| 43 | { | ||
| 44 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 45 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 46 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 47 | Runeerror = 0x80, /* decoding error in UTF */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * rune routines | ||
| 52 | */ | ||
| 53 | extern int runetochar(char*, Rune*); | ||
| 54 | extern int chartorune(Rune*, char*); | ||
| 55 | extern int runelen(long); | ||
| 56 | extern int runenlen(Rune*, int); | ||
| 57 | extern int fullrune(char*, int); | ||
| 58 | extern int utflen(char*); | ||
| 59 | extern int utfnlen(char*, long); | ||
| 60 | extern char* utfrune(char*, long); | ||
| 61 | extern char* utfrrune(char*, long); | ||
| 62 | extern char* utfutf(char*, char*); | ||
| 63 | extern char* utfecpy(char*, char*, char*); | ||
| 64 | |||
| 65 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 66 | extern Rune* runestrchr(Rune*, Rune); | ||
| 67 | extern int runestrcmp(Rune*, Rune*); | ||
| 68 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 69 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 70 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 71 | extern Rune* runestrdup(Rune*); | ||
| 72 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 73 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 74 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 75 | extern long runestrlen(Rune*); | ||
| 76 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 77 | |||
| 78 | extern Rune tolowerrune(Rune); | ||
| 79 | extern Rune totitlerune(Rune); | ||
| 80 | extern Rune toupperrune(Rune); | ||
| 81 | extern int isalpharune(Rune); | ||
| 82 | extern int islowerrune(Rune); | ||
| 83 | extern int isspacerune(Rune); | ||
| 84 | extern int istitlerune(Rune); | ||
| 85 | extern int isupperrune(Rune); | ||
| 86 | |||
| 87 | /* | ||
| 88 | * malloc | ||
| 89 | */ | ||
| 90 | extern void* malloc(ulong); | ||
| 91 | extern void* mallocz(ulong, int); | ||
| 92 | extern void free(void*); | ||
| 93 | extern ulong msize(void*); | ||
| 94 | extern void* calloc(ulong, ulong); | ||
| 95 | extern void* realloc(void*, ulong); | ||
| 96 | extern void setmalloctag(void*, ulong); | ||
| 97 | extern void setrealloctag(void*, ulong); | ||
| 98 | extern ulong getmalloctag(void*); | ||
| 99 | extern ulong getrealloctag(void*); | ||
| 100 | extern void* malloctopoolblock(void*); | ||
| 101 | |||
| 102 | /* | ||
| 103 | * print routines | ||
| 104 | */ | ||
| 105 | typedef struct Fmt Fmt; | ||
| 106 | struct Fmt{ | ||
| 107 | uchar runes; /* output buffer is runes or chars? */ | ||
| 108 | void *start; /* of buffer */ | ||
| 109 | void *to; /* current place in the buffer */ | ||
| 110 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 111 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 112 | void *farg; /* to make flush a closure */ | ||
| 113 | int nfmt; /* num chars formatted so far */ | ||
| 114 | va_list args; /* args passed to dofmt */ | ||
| 115 | int r; /* % format Rune */ | ||
| 116 | int width; | ||
| 117 | int prec; | ||
| 118 | ulong flags; | ||
| 119 | }; | ||
| 120 | |||
| 121 | enum{ | ||
| 122 | FmtWidth = 1, | ||
| 123 | FmtLeft = FmtWidth << 1, | ||
| 124 | FmtPrec = FmtLeft << 1, | ||
| 125 | FmtSharp = FmtPrec << 1, | ||
| 126 | FmtSpace = FmtSharp << 1, | ||
| 127 | FmtSign = FmtSpace << 1, | ||
| 128 | FmtZero = FmtSign << 1, | ||
| 129 | FmtUnsigned = FmtZero << 1, | ||
| 130 | FmtShort = FmtUnsigned << 1, | ||
| 131 | FmtLong = FmtShort << 1, | ||
| 132 | FmtVLong = FmtLong << 1, | ||
| 133 | FmtComma = FmtVLong << 1, | ||
| 134 | FmtByte = FmtComma << 1, | ||
| 135 | |||
| 136 | FmtFlag = FmtByte << 1 | ||
| 137 | }; | ||
| 138 | |||
| 139 | extern int print(char*, ...); | ||
| 140 | extern char* seprint(char*, char*, char*, ...); | ||
| 141 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 142 | extern int snprint(char*, int, char*, ...); | ||
| 143 | extern int vsnprint(char*, int, char*, va_list); | ||
| 144 | extern char* smprint(char*, ...); | ||
| 145 | extern char* vsmprint(char*, va_list); | ||
| 146 | extern int sprint(char*, char*, ...); | ||
| 147 | extern int fprint(int, char*, ...); | ||
| 148 | extern int vfprint(int, char*, va_list); | ||
| 149 | |||
| 150 | extern int runesprint(Rune*, char*, ...); | ||
| 151 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 152 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 153 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 154 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 155 | extern Rune* runesmprint(char*, ...); | ||
| 156 | extern Rune* runevsmprint(char*, va_list); | ||
| 157 | |||
| 158 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 159 | extern int fmtfdflush(Fmt*); | ||
| 160 | extern int fmtstrinit(Fmt*); | ||
| 161 | extern char* fmtstrflush(Fmt*); | ||
| 162 | extern int runefmtstrinit(Fmt*); | ||
| 163 | extern Rune* runefmtstrflush(Fmt*); | ||
| 164 | |||
| 165 | #pragma varargck argpos fmtprint 2 | ||
| 166 | #pragma varargck argpos fprint 2 | ||
| 167 | #pragma varargck argpos print 1 | ||
| 168 | #pragma varargck argpos runeseprint 3 | ||
| 169 | #pragma varargck argpos runesmprint 1 | ||
| 170 | #pragma varargck argpos runesnprint 3 | ||
| 171 | #pragma varargck argpos runesprint 2 | ||
| 172 | #pragma varargck argpos seprint 3 | ||
| 173 | #pragma varargck argpos smprint 1 | ||
| 174 | #pragma varargck argpos snprint 3 | ||
| 175 | #pragma varargck argpos sprint 2 | ||
| 176 | #pragma varargck argpos vseprint 3 | ||
| 177 | #pragma varargck argpos vsnprint 3 | ||
| 178 | |||
| 179 | #pragma varargck type "lld" vlong | ||
| 180 | #pragma varargck type "llx" vlong | ||
| 181 | #pragma varargck type "lld" uvlong | ||
| 182 | #pragma varargck type "llx" uvlong | ||
| 183 | #pragma varargck type "ld" long | ||
| 184 | #pragma varargck type "lx" long | ||
| 185 | #pragma varargck type "ld" ulong | ||
| 186 | #pragma varargck type "lx" ulong | ||
| 187 | #pragma varargck type "d" int | ||
| 188 | #pragma varargck type "x" int | ||
| 189 | #pragma varargck type "c" int | ||
| 190 | #pragma varargck type "C" int | ||
| 191 | #pragma varargck type "d" uint | ||
| 192 | #pragma varargck type "x" uint | ||
| 193 | #pragma varargck type "c" uint | ||
| 194 | #pragma varargck type "C" uint | ||
| 195 | #pragma varargck type "f" double | ||
| 196 | #pragma varargck type "e" double | ||
| 197 | #pragma varargck type "g" double | ||
| 198 | #pragma varargck type "s" char* | ||
| 199 | #pragma varargck type "q" char* | ||
| 200 | #pragma varargck type "S" Rune* | ||
| 201 | #pragma varargck type "Q" Rune* | ||
| 202 | #pragma varargck type "r" void | ||
| 203 | #pragma varargck type "%" void | ||
| 204 | #pragma varargck type "n" int* | ||
| 205 | #pragma varargck type "p" void* | ||
| 206 | #pragma varargck flag ',' | ||
| 207 | #pragma varargck type "<" void* | ||
| 208 | #pragma varargck type "[" void* | ||
| 209 | #pragma varargck type "H" void* | ||
| 210 | |||
| 211 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 212 | extern int dofmt(Fmt*, char*); | ||
| 213 | extern int dorfmt(Fmt*, Rune*); | ||
| 214 | extern int fmtprint(Fmt*, char*, ...); | ||
| 215 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 216 | extern int fmtrune(Fmt*, int); | ||
| 217 | extern int fmtstrcpy(Fmt*, char*); | ||
| 218 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 219 | /* | ||
| 220 | * error string for %r | ||
| 221 | * supplied on per os basis, not part of fmt library | ||
| 222 | */ | ||
| 223 | extern int errfmt(Fmt *f); | ||
| 224 | |||
| 225 | /* | ||
| 226 | * quoted strings | ||
| 227 | */ | ||
| 228 | extern char *unquotestrdup(char*); | ||
| 229 | extern Rune *unquoterunestrdup(Rune*); | ||
| 230 | extern char *quotestrdup(char*); | ||
| 231 | extern Rune *quoterunestrdup(Rune*); | ||
| 232 | extern int quotestrfmt(Fmt*); | ||
| 233 | extern int quoterunestrfmt(Fmt*); | ||
| 234 | extern void quotefmtinstall(void); | ||
| 235 | extern int (*doquote)(int); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * random number | ||
| 239 | */ | ||
| 240 | extern void srand(long); | ||
| 241 | extern int rand(void); | ||
| 242 | extern int nrand(int); | ||
| 243 | extern long lrand(void); | ||
| 244 | extern long lnrand(long); | ||
| 245 | extern double frand(void); | ||
| 246 | extern ulong truerand(void); | ||
| 247 | extern ulong ntruerand(ulong); | ||
| 248 | |||
| 249 | /* | ||
| 250 | * math | ||
| 251 | */ | ||
| 252 | extern ulong getfcr(void); | ||
| 253 | extern void setfsr(ulong); | ||
| 254 | extern ulong getfsr(void); | ||
| 255 | extern void setfcr(ulong); | ||
| 256 | extern double NaN(void); | ||
| 257 | extern double Inf(int); | ||
| 258 | extern int isNaN(double); | ||
| 259 | extern int isInf(double, int); | ||
| 260 | |||
| 261 | extern double pow(double, double); | ||
| 262 | extern double atan2(double, double); | ||
| 263 | extern double fabs(double); | ||
| 264 | extern double atan(double); | ||
| 265 | extern double log(double); | ||
| 266 | extern double log10(double); | ||
| 267 | extern double exp(double); | ||
| 268 | extern double floor(double); | ||
| 269 | extern double ceil(double); | ||
| 270 | extern double hypot(double, double); | ||
| 271 | extern double sin(double); | ||
| 272 | extern double cos(double); | ||
| 273 | extern double tan(double); | ||
| 274 | extern double asin(double); | ||
| 275 | extern double acos(double); | ||
| 276 | extern double sinh(double); | ||
| 277 | extern double cosh(double); | ||
| 278 | extern double tanh(double); | ||
| 279 | extern double sqrt(double); | ||
| 280 | extern double fmod(double, double); | ||
| 281 | |||
| 282 | #define HUGE 3.4028234e38 | ||
| 283 | #define PIO2 1.570796326794896619231e0 | ||
| 284 | #define PI (PIO2+PIO2) | ||
| 285 | |||
| 286 | /* | ||
| 287 | * Time-of-day | ||
| 288 | */ | ||
| 289 | |||
| 290 | typedef | ||
| 291 | struct Tm | ||
| 292 | { | ||
| 293 | int sec; | ||
| 294 | int min; | ||
| 295 | int hour; | ||
| 296 | int mday; | ||
| 297 | int mon; | ||
| 298 | int year; | ||
| 299 | int wday; | ||
| 300 | int yday; | ||
| 301 | char zone[4]; | ||
| 302 | int tzoff; | ||
| 303 | } Tm; | ||
| 304 | |||
| 305 | extern Tm* gmtime(long); | ||
| 306 | extern Tm* localtime(long); | ||
| 307 | extern char* asctime(Tm*); | ||
| 308 | extern char* ctime(long); | ||
| 309 | extern double cputime(void); | ||
| 310 | extern long times(long*); | ||
| 311 | extern long tm2sec(Tm*); | ||
| 312 | extern vlong nsec(void); | ||
| 313 | |||
| 314 | /* | ||
| 315 | * one-of-a-kind | ||
| 316 | */ | ||
| 317 | enum | ||
| 318 | { | ||
| 319 | PNPROC = 1, | ||
| 320 | PNGROUP = 2, | ||
| 321 | }; | ||
| 322 | |||
| 323 | extern void _assert(char*); | ||
| 324 | extern int abs(int); | ||
| 325 | extern int atexit(void(*)(void)); | ||
| 326 | extern void atexitdont(void(*)(void)); | ||
| 327 | extern int atnotify(int(*)(void*, char*), int); | ||
| 328 | extern double atof(char*); | ||
| 329 | extern int atoi(char*); | ||
| 330 | extern long atol(char*); | ||
| 331 | extern double charstod(int(*)(void*), void*); | ||
| 332 | extern char* cleanname(char*); | ||
| 333 | extern int decrypt(void*, void*, int); | ||
| 334 | extern int encrypt(void*, void*, int); | ||
| 335 | extern int dec64(uchar*, int, char*, int); | ||
| 336 | extern int enc64(char*, int, uchar*, int); | ||
| 337 | extern int dec32(uchar*, int, char*, int); | ||
| 338 | extern int enc32(char*, int, uchar*, int); | ||
| 339 | extern int dec16(uchar*, int, char*, int); | ||
| 340 | extern int enc16(char*, int, uchar*, int); | ||
| 341 | extern int encodefmt(Fmt*); | ||
| 342 | extern void exits(char*); | ||
| 343 | extern double frexp(double, int*); | ||
| 344 | extern uintptr getcallerpc(void*); | ||
| 345 | extern char* getenv(char*); | ||
| 346 | extern int getfields(char*, char**, int, int, char*); | ||
| 347 | extern char* getuser(void); | ||
| 348 | extern char* getwd(char*, int); | ||
| 349 | extern int iounit(int); | ||
| 350 | extern long labs(long); | ||
| 351 | extern double ldexp(double, int); | ||
| 352 | extern void longjmp(jmp_buf, int); | ||
| 353 | extern char* mktemp(char*); | ||
| 354 | extern double modf(double, double*); | ||
| 355 | extern int netcrypt(void*, void*); | ||
| 356 | extern void notejmp(void*, jmp_buf, int); | ||
| 357 | extern void perror(char*); | ||
| 358 | extern int postnote(int, int, char *); | ||
| 359 | extern double pow10(int); | ||
| 360 | extern double ipow10(int); | ||
| 361 | extern int putenv(char*, char*); | ||
| 362 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 363 | extern void* sbrk(ulong); | ||
| 364 | extern int setjmp(jmp_buf); | ||
| 365 | extern double strtod(char*, char**); | ||
| 366 | extern long strtol(char*, char**, int); | ||
| 367 | extern ulong strtoul(char*, char**, int); | ||
| 368 | extern vlong strtoll(char*, char**, int); | ||
| 369 | extern uvlong strtoull(char*, char**, int); | ||
| 370 | extern void sysfatal(char*, ...); | ||
| 371 | #pragma varargck argpos sysfatal 1 | ||
| 372 | extern void syslog(int, char*, char*, ...); | ||
| 373 | #pragma varargck argpos syslog 3 | ||
| 374 | extern long time(long*); | ||
| 375 | extern int tolower(int); | ||
| 376 | extern int toupper(int); | ||
| 377 | |||
| 378 | /* | ||
| 379 | * synchronization | ||
| 380 | */ | ||
| 381 | typedef | ||
| 382 | struct Lock { | ||
| 383 | int val; | ||
| 384 | } Lock; | ||
| 385 | |||
| 386 | extern int _tas(int*); | ||
| 387 | |||
| 388 | extern void lock(Lock*); | ||
| 389 | extern void unlock(Lock*); | ||
| 390 | extern int canlock(Lock*); | ||
| 391 | |||
| 392 | typedef struct QLp QLp; | ||
| 393 | struct QLp | ||
| 394 | { | ||
| 395 | int inuse; | ||
| 396 | QLp *next; | ||
| 397 | char state; | ||
| 398 | }; | ||
| 399 | |||
| 400 | typedef | ||
| 401 | struct QLock | ||
| 402 | { | ||
| 403 | Lock lock; | ||
| 404 | int locked; | ||
| 405 | QLp *head; | ||
| 406 | QLp *tail; | ||
| 407 | } QLock; | ||
| 408 | |||
| 409 | extern void qlock(QLock*); | ||
| 410 | extern void qunlock(QLock*); | ||
| 411 | extern int canqlock(QLock*); | ||
| 412 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 413 | |||
| 414 | typedef | ||
| 415 | struct RWLock | ||
| 416 | { | ||
| 417 | Lock lock; | ||
| 418 | int readers; /* number of readers */ | ||
| 419 | int writer; /* number of writers */ | ||
| 420 | QLp *head; /* list of waiting processes */ | ||
| 421 | QLp *tail; | ||
| 422 | } RWLock; | ||
| 423 | |||
| 424 | extern int canrlock(RWLock*); | ||
| 425 | extern int canwlock(RWLock*); | ||
| 426 | extern void rlock(RWLock*); | ||
| 427 | extern void runlock(RWLock*); | ||
| 428 | extern void wlock(RWLock*); | ||
| 429 | extern void wunlock(RWLock*); | ||
| 430 | |||
| 431 | extern void** privalloc(void); | ||
| 432 | extern void privfree(void**); | ||
| 433 | |||
| 434 | /* | ||
| 435 | * network dialing | ||
| 436 | */ | ||
| 437 | #define NETPATHLEN 40 | ||
| 438 | extern int accept(int, char*); | ||
| 439 | extern int announce(char*, char*); | ||
| 440 | extern int dial(char*, char*, char*, int*); | ||
| 441 | extern void setnetmtpt(char*, int, char*); | ||
| 442 | extern int hangup(int); | ||
| 443 | extern int listen(char*, char*); | ||
| 444 | extern char* netmkaddr(char*, char*, char*); | ||
| 445 | extern int reject(int, char*, char*); | ||
| 446 | |||
| 447 | /* | ||
| 448 | * system calls | ||
| 449 | * | ||
| 450 | */ | ||
| 451 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 452 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 453 | #define ERRMAX 128 /* max length of error string */ | ||
| 454 | |||
| 455 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 456 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 457 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 458 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 459 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 460 | #define MCACHE 0x0010 /* cache some data */ | ||
| 461 | #define MMASK 0x0017 /* all bits on */ | ||
| 462 | |||
| 463 | #define OREAD 0 /* open for read */ | ||
| 464 | #define OWRITE 1 /* write */ | ||
| 465 | #define ORDWR 2 /* read and write */ | ||
| 466 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 467 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 468 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 469 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 470 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 471 | |||
| 472 | #define AEXIST 0 /* accessible: exists */ | ||
| 473 | #define AEXEC 1 /* execute access */ | ||
| 474 | #define AWRITE 2 /* write access */ | ||
| 475 | #define AREAD 4 /* read access */ | ||
| 476 | |||
| 477 | |||
| 478 | /* Segattch */ | ||
| 479 | #define SG_RONLY 0040 /* read only */ | ||
| 480 | #define SG_CEXEC 0100 /* detach on exec */ | ||
| 481 | |||
| 482 | #define NCONT 0 /* continue after note */ | ||
| 483 | #define NDFLT 1 /* terminate after note */ | ||
| 484 | #define NSAVE 2 /* clear note but hold state */ | ||
| 485 | #define NRSTR 3 /* restore saved state */ | ||
| 486 | |||
| 487 | /* rfork */ | ||
| 488 | enum | ||
| 489 | { | ||
| 490 | RFNAMEG = (1<<0), | ||
| 491 | RFENVG = (1<<1), | ||
| 492 | RFFDG = (1<<2), | ||
| 493 | RFNOTEG = (1<<3), | ||
| 494 | RFPROC = (1<<4), | ||
| 495 | RFMEM = (1<<5), | ||
| 496 | RFNOWAIT = (1<<6), | ||
| 497 | RFCNAMEG = (1<<10), | ||
| 498 | RFCENVG = (1<<11), | ||
| 499 | RFCFDG = (1<<12), | ||
| 500 | RFREND = (1<<13), | ||
| 501 | RFNOMNT = (1<<14) | ||
| 502 | }; | ||
| 503 | |||
| 504 | /* bits in Qid.type */ | ||
| 505 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 506 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 507 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 508 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 509 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 510 | #define QTFILE 0x00 /* plain file */ | ||
| 511 | |||
| 512 | /* bits in Dir.mode */ | ||
| 513 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 514 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 515 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 516 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 517 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 518 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 519 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 520 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 521 | |||
| 522 | typedef | ||
| 523 | struct Qid | ||
| 524 | { | ||
| 525 | uvlong path; | ||
| 526 | ulong vers; | ||
| 527 | uchar type; | ||
| 528 | } Qid; | ||
| 529 | |||
| 530 | typedef | ||
| 531 | struct Dir { | ||
| 532 | /* system-modified data */ | ||
| 533 | ushort type; /* server type */ | ||
| 534 | uint dev; /* server subtype */ | ||
| 535 | /* file data */ | ||
| 536 | Qid qid; /* unique id from server */ | ||
| 537 | ulong mode; /* permissions */ | ||
| 538 | ulong atime; /* last read time */ | ||
| 539 | ulong mtime; /* last write time */ | ||
| 540 | vlong length; /* file length */ | ||
| 541 | char *name; /* last element of path */ | ||
| 542 | char *uid; /* owner name */ | ||
| 543 | char *gid; /* group name */ | ||
| 544 | char *muid; /* last modifier name */ | ||
| 545 | } Dir; | ||
| 546 | |||
| 547 | extern Dir* dirstat(char*); | ||
| 548 | extern Dir* dirfstat(int); | ||
| 549 | extern int dirwstat(char*, Dir*); | ||
| 550 | extern int dirfwstat(int, Dir*); | ||
| 551 | extern long dirread(int, Dir**); | ||
| 552 | extern void nulldir(Dir*); | ||
| 553 | extern long dirreadall(int, Dir**); | ||
| 554 | |||
| 555 | typedef | ||
| 556 | struct Waitmsg | ||
| 557 | { | ||
| 558 | int pid; /* of loved one */ | ||
| 559 | ulong time[3]; /* of loved one & descendants */ | ||
| 560 | char *msg; | ||
| 561 | } Waitmsg; | ||
| 562 | |||
| 563 | typedef | ||
| 564 | struct IOchunk | ||
| 565 | { | ||
| 566 | void *addr; | ||
| 567 | ulong len; | ||
| 568 | } IOchunk; | ||
| 569 | |||
| 570 | extern void _exits(char*); | ||
| 571 | |||
| 572 | extern void abort(void); | ||
| 573 | extern int access(char*, int); | ||
| 574 | extern long alarm(ulong); | ||
| 575 | extern int await(char*, int); | ||
| 576 | extern int bind(char*, char*, int); | ||
| 577 | extern int brk(void*); | ||
| 578 | extern int chdir(char*); | ||
| 579 | extern int close(int); | ||
| 580 | extern int create(char*, int, ulong); | ||
| 581 | extern int dup(int, int); | ||
| 582 | extern int errstr(char*, uint); | ||
| 583 | extern int exec(char*, char*[]); | ||
| 584 | extern int execl(char*, ...); | ||
| 585 | extern int fork(void); | ||
| 586 | extern int rfork(int); | ||
| 587 | extern int fauth(int, char*); | ||
| 588 | extern int fstat(int, uchar*, int); | ||
| 589 | extern int fwstat(int, uchar*, int); | ||
| 590 | extern int fversion(int, int, char*, int); | ||
| 591 | extern int mount(int, int, char*, int, char*); | ||
| 592 | extern int unmount(char*, char*); | ||
| 593 | extern int noted(int); | ||
| 594 | extern int notify(void(*)(void*, char*)); | ||
| 595 | extern int open(char*, int); | ||
| 596 | extern int fd2path(int, char*, int); | ||
| 597 | extern int pipe(int*); | ||
| 598 | extern long pread(int, void*, long, vlong); | ||
| 599 | extern long preadv(int, IOchunk*, int, vlong); | ||
| 600 | extern long pwrite(int, void*, long, vlong); | ||
| 601 | extern long pwritev(int, IOchunk*, int, vlong); | ||
| 602 | extern long read(int, void*, long); | ||
| 603 | extern long readn(int, void*, long); | ||
| 604 | extern long readv(int, IOchunk*, int); | ||
| 605 | extern int remove(char*); | ||
| 606 | extern void* sbrk(ulong); | ||
| 607 | extern long oseek(int, long, int); | ||
| 608 | extern vlong seek(int, vlong, int); | ||
| 609 | extern long segattach(int, char*, void*, ulong); | ||
| 610 | extern int segbrk(void*, void*); | ||
| 611 | extern int segdetach(void*); | ||
| 612 | extern int segflush(void*, ulong); | ||
| 613 | extern int segfree(void*, ulong); | ||
| 614 | extern int sleep(long); | ||
| 615 | extern int stat(char*, uchar*, int); | ||
| 616 | extern Waitmsg* wait(void); | ||
| 617 | extern int waitpid(void); | ||
| 618 | extern long write(int, void*, long); | ||
| 619 | extern long writev(int, IOchunk*, int); | ||
| 620 | extern int wstat(char*, uchar*, int); | ||
| 621 | extern void* rendezvous(void*, void*); | ||
| 622 | |||
| 623 | extern int getpid(void); | ||
| 624 | extern int getppid(void); | ||
| 625 | extern void rerrstr(char*, uint); | ||
| 626 | extern char* sysname(void); | ||
| 627 | extern void werrstr(char*, ...); | ||
| 628 | #pragma varargck argpos werrstr 1 | ||
| 629 | |||
| 630 | extern char *argv0; | ||
| 631 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 632 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 633 | argc--, argv++) {\ | ||
| 634 | char *_args, *_argt;\ | ||
| 635 | Rune _argc;\ | ||
| 636 | _args = &argv[0][1];\ | ||
| 637 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 638 | argc--; argv++; break;\ | ||
| 639 | }\ | ||
| 640 | _argc = 0;\ | ||
| 641 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 642 | switch(_argc) | ||
| 643 | #define ARGEND SET(_argt);USED(_argt,_argc,_args);}USED(argv, argc); | ||
| 644 | #define ARGF() (_argt=_args, _args="",\ | ||
| 645 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 646 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 647 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 648 | |||
| 649 | #define ARGC() _argc | ||
| 650 | |||
| 651 | /* | ||
| 652 | * Extensions for Inferno to basic libc.h | ||
| 653 | */ | ||
| 654 | |||
| 655 | #define setbinmode() | ||
| 656 | #undef __LITTLE_ENDIAN | ||
| 657 | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | typedef unsigned short ushort; | ||
| 3 | typedef unsigned char uchar; | ||
| 4 | typedef unsigned long ulong; | ||
| 5 | typedef unsigned int uint; | ||
| 6 | typedef signed char schar; | ||
| 7 | typedef long long vlong; | ||
| 8 | typedef unsigned long long uvlong; | ||
| 9 | typedef unsigned long uintptr; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC 0 | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | |||
| 22 | /* FPSCR */ | ||
| 23 | #define FPSFX (1<<31) /* exception summary (sticky) */ | ||
| 24 | #define FPSEX (1<<30) /* enabled exception summary */ | ||
| 25 | #define FPSVX (1<<29) /* invalid operation exception summary */ | ||
| 26 | #define FPSOX (1<<28) /* overflow exception OX (sticky) */ | ||
| 27 | #define FPSUX (1<<27) /* underflow exception UX (sticky) */ | ||
| 28 | #define FPSZX (1<<26) /* zero divide exception ZX (sticky) */ | ||
| 29 | #define FPSXX (1<<25) /* inexact exception XX (sticky) */ | ||
| 30 | #define FPSVXSNAN (1<<24) /* invalid operation exception for SNaN (sticky) */ | ||
| 31 | #define FPSVXISI (1<<23) /* invalid operation exception for ∞-∞ (sticky) */ | ||
| 32 | #define FPSVXIDI (1<<22) /* invalid operation exception for ∞/∞ (sticky) */ | ||
| 33 | #define FPSVXZDZ (1<<21) /* invalid operation exception for 0/0 (sticky) */ | ||
| 34 | #define FPSVXIMZ (1<<20) /* invalid operation exception for ∞*0 (sticky) */ | ||
| 35 | #define FPSVXVC (1<<19) /* invalid operation exception for invalid compare (sticky) */ | ||
| 36 | #define FPSFR (1<<18) /* fraction rounded */ | ||
| 37 | #define FPSFI (1<<17) /* fraction inexact */ | ||
| 38 | #define FPSFPRF (1<<16) /* floating point result class */ | ||
| 39 | #define FPSFPCC (0xF<<12) /* <, >, =, unordered */ | ||
| 40 | #define FPVXCVI (1<<8) /* enable exception for invalid integer convert (sticky) */ | ||
| 41 | #define FPVE (1<<7) /* invalid operation exception enable */ | ||
| 42 | #define FPOVFL (1<<6) /* enable overflow exceptions */ | ||
| 43 | #define FPUNFL (1<<5) /* enable underflow */ | ||
| 44 | #define FPZDIV (1<<4) /* enable zero divide */ | ||
| 45 | #define FPINEX (1<<3) /* enable inexact exceptions */ | ||
| 46 | #define FPRMASK (3<<0) /* rounding mode */ | ||
| 47 | #define FPRNR (0<<0) | ||
| 48 | #define FPRZ (1<<0) | ||
| 49 | #define FPRPINF (2<<0) | ||
| 50 | #define FPRNINF (3<<0) | ||
| 51 | #define FPPEXT 0 | ||
| 52 | #define FPPSGL 0 | ||
| 53 | #define FPPDBL 0 | ||
| 54 | #define FPPMASK 0 | ||
| 55 | #define FPINVAL FPVE | ||
| 56 | |||
| 57 | #define FPAOVFL FPSOX | ||
| 58 | #define FPAINEX FPSXX | ||
| 59 | #define FPAUNFL FPSUX | ||
| 60 | #define FPAZDIV FPSZX | ||
| 61 | #define FPAINVAL FPSVX | ||
| 62 | |||
| 63 | union FPdbleword | ||
| 64 | { | ||
| 65 | double x; | ||
| 66 | struct { /* big endian */ | ||
| 67 | ulong hi; | ||
| 68 | ulong lo; | ||
| 69 | }; | ||
| 70 | }; | ||
| 71 | |||
| 72 | typedef char* va_list; | ||
| 73 | #define va_start(list, start) list =\ | ||
| 74 | (sizeof(start) < 4?\ | ||
| 75 | (char*)((int*)&(start)+1):\ | ||
| 76 | (char*)(&(start)+1)) | ||
| 77 | #define va_end(list)\ | ||
| 78 | USED(list) | ||
| 79 | #define va_arg(list, mode)\ | ||
| 80 | ((sizeof(mode) == 1)?\ | ||
| 81 | ((mode*)(list += 4))[-1]:\ | ||
| 82 | (sizeof(mode) == 2)?\ | ||
| 83 | ((mode*)(list += 4))[-1]:\ | ||
| 84 | ((mode*)(list += sizeof(mode)))[-1]) | ||
| @@ -0,0 +1,22 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc** Xup; | ||
| 8 | #define up (*Xup) | ||
| 9 | |||
| 10 | typedef struct FPU FPU; | ||
| 11 | |||
| 12 | /* | ||
| 13 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 14 | */ | ||
| 15 | struct FPU | ||
| 16 | { | ||
| 17 | ulong fsr; | ||
| 18 | }; | ||
| 19 | |||
| 20 | typedef jmp_buf osjmpbuf; | ||
| 21 | #define ossetjmp(buf) setjmp(buf) | ||
| 22 | |||
| @@ -0,0 +1,657 @@ | |||
| 1 | #include <u.h> | ||
| 2 | typedef unsigned long size_t; | ||
| 3 | |||
| 4 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 5 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 6 | #define assert(x) if(x){}else _assert("x") | ||
| 7 | |||
| 8 | /* | ||
| 9 | * mem routines | ||
| 10 | */ | ||
| 11 | extern void* memccpy(void*, void*, int, ulong); | ||
| 12 | extern void* memset(void*, int, ulong); | ||
| 13 | extern int memcmp(void*, void*, ulong); | ||
| 14 | extern void* memcpy(void*, void*, ulong); | ||
| 15 | extern void* memmove(void*, void*, ulong); | ||
| 16 | extern void* memchr(void*, int, ulong); | ||
| 17 | |||
| 18 | /* | ||
| 19 | * string routines | ||
| 20 | */ | ||
| 21 | extern char* strcat(char*, char*); | ||
| 22 | extern char* strchr(char*, int); | ||
| 23 | extern int strcmp(char*, char*); | ||
| 24 | extern char* strcpy(char*, char*); | ||
| 25 | extern char* strecpy(char*, char*, char*); | ||
| 26 | extern char* strdup(char*); | ||
| 27 | extern char* strncat(char*, char*, long); | ||
| 28 | extern char* strncpy(char*, char*, long); | ||
| 29 | extern int strncmp(char*, char*, long); | ||
| 30 | extern char* strpbrk(char*, char*); | ||
| 31 | extern char* strrchr(char*, int); | ||
| 32 | extern char* strtok(char*, char*); | ||
| 33 | extern long strlen(char*); | ||
| 34 | extern long strspn(char*, char*); | ||
| 35 | extern long strcspn(char*, char*); | ||
| 36 | extern char* strstr(char*, char*); | ||
| 37 | extern int cistrncmp(char*, char*, int); | ||
| 38 | extern int cistrcmp(char*, char*); | ||
| 39 | extern char* cistrstr(char*, char*); | ||
| 40 | extern int tokenize(char*, char**, int); | ||
| 41 | |||
| 42 | enum | ||
| 43 | { | ||
| 44 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 45 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 46 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 47 | Runeerror = 0x80, /* decoding error in UTF */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * rune routines | ||
| 52 | */ | ||
| 53 | extern int runetochar(char*, Rune*); | ||
| 54 | extern int chartorune(Rune*, char*); | ||
| 55 | extern int runelen(long); | ||
| 56 | extern int runenlen(Rune*, int); | ||
| 57 | extern int fullrune(char*, int); | ||
| 58 | extern int utflen(char*); | ||
| 59 | extern int utfnlen(char*, long); | ||
| 60 | extern char* utfrune(char*, long); | ||
| 61 | extern char* utfrrune(char*, long); | ||
| 62 | extern char* utfutf(char*, char*); | ||
| 63 | extern char* utfecpy(char*, char*, char*); | ||
| 64 | |||
| 65 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 66 | extern Rune* runestrchr(Rune*, Rune); | ||
| 67 | extern int runestrcmp(Rune*, Rune*); | ||
| 68 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 69 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 70 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 71 | extern Rune* runestrdup(Rune*); | ||
| 72 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 73 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 74 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 75 | extern long runestrlen(Rune*); | ||
| 76 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 77 | |||
| 78 | extern Rune tolowerrune(Rune); | ||
| 79 | extern Rune totitlerune(Rune); | ||
| 80 | extern Rune toupperrune(Rune); | ||
| 81 | extern int isalpharune(Rune); | ||
| 82 | extern int islowerrune(Rune); | ||
| 83 | extern int isspacerune(Rune); | ||
| 84 | extern int istitlerune(Rune); | ||
| 85 | extern int isupperrune(Rune); | ||
| 86 | |||
| 87 | /* | ||
| 88 | * malloc | ||
| 89 | */ | ||
| 90 | extern void* malloc(ulong); | ||
| 91 | extern void* mallocz(ulong, int); | ||
| 92 | extern void free(void*); | ||
| 93 | extern ulong msize(void*); | ||
| 94 | extern void* calloc(ulong, ulong); | ||
| 95 | extern void* realloc(void*, ulong); | ||
| 96 | extern void setmalloctag(void*, ulong); | ||
| 97 | extern void setrealloctag(void*, ulong); | ||
| 98 | extern ulong getmalloctag(void*); | ||
| 99 | extern ulong getrealloctag(void*); | ||
| 100 | extern void* malloctopoolblock(void*); | ||
| 101 | |||
| 102 | /* | ||
| 103 | * print routines | ||
| 104 | */ | ||
| 105 | typedef struct Fmt Fmt; | ||
| 106 | struct Fmt{ | ||
| 107 | uchar runes; /* output buffer is runes or chars? */ | ||
| 108 | void *start; /* of buffer */ | ||
| 109 | void *to; /* current place in the buffer */ | ||
| 110 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 111 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 112 | void *farg; /* to make flush a closure */ | ||
| 113 | int nfmt; /* num chars formatted so far */ | ||
| 114 | va_list args; /* args passed to dofmt */ | ||
| 115 | int r; /* % format Rune */ | ||
| 116 | int width; | ||
| 117 | int prec; | ||
| 118 | ulong flags; | ||
| 119 | }; | ||
| 120 | |||
| 121 | enum{ | ||
| 122 | FmtWidth = 1, | ||
| 123 | FmtLeft = FmtWidth << 1, | ||
| 124 | FmtPrec = FmtLeft << 1, | ||
| 125 | FmtSharp = FmtPrec << 1, | ||
| 126 | FmtSpace = FmtSharp << 1, | ||
| 127 | FmtSign = FmtSpace << 1, | ||
| 128 | FmtZero = FmtSign << 1, | ||
| 129 | FmtUnsigned = FmtZero << 1, | ||
| 130 | FmtShort = FmtUnsigned << 1, | ||
| 131 | FmtLong = FmtShort << 1, | ||
| 132 | FmtVLong = FmtLong << 1, | ||
| 133 | FmtComma = FmtVLong << 1, | ||
| 134 | FmtByte = FmtComma << 1, | ||
| 135 | |||
| 136 | FmtFlag = FmtByte << 1 | ||
| 137 | }; | ||
| 138 | |||
| 139 | extern int print(char*, ...); | ||
| 140 | extern char* seprint(char*, char*, char*, ...); | ||
| 141 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 142 | extern int snprint(char*, int, char*, ...); | ||
| 143 | extern int vsnprint(char*, int, char*, va_list); | ||
| 144 | extern char* smprint(char*, ...); | ||
| 145 | extern char* vsmprint(char*, va_list); | ||
| 146 | extern int sprint(char*, char*, ...); | ||
| 147 | extern int fprint(int, char*, ...); | ||
| 148 | extern int vfprint(int, char*, va_list); | ||
| 149 | |||
| 150 | extern int runesprint(Rune*, char*, ...); | ||
| 151 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 152 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 153 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 154 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 155 | extern Rune* runesmprint(char*, ...); | ||
| 156 | extern Rune* runevsmprint(char*, va_list); | ||
| 157 | |||
| 158 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 159 | extern int fmtfdflush(Fmt*); | ||
| 160 | extern int fmtstrinit(Fmt*); | ||
| 161 | extern char* fmtstrflush(Fmt*); | ||
| 162 | extern int runefmtstrinit(Fmt*); | ||
| 163 | extern Rune* runefmtstrflush(Fmt*); | ||
| 164 | |||
| 165 | #pragma varargck argpos fmtprint 2 | ||
| 166 | #pragma varargck argpos fprint 2 | ||
| 167 | #pragma varargck argpos print 1 | ||
| 168 | #pragma varargck argpos runeseprint 3 | ||
| 169 | #pragma varargck argpos runesmprint 1 | ||
| 170 | #pragma varargck argpos runesnprint 3 | ||
| 171 | #pragma varargck argpos runesprint 2 | ||
| 172 | #pragma varargck argpos seprint 3 | ||
| 173 | #pragma varargck argpos smprint 1 | ||
| 174 | #pragma varargck argpos snprint 3 | ||
| 175 | #pragma varargck argpos sprint 2 | ||
| 176 | #pragma varargck argpos vseprint 3 | ||
| 177 | #pragma varargck argpos vsnprint 3 | ||
| 178 | |||
| 179 | #pragma varargck type "lld" vlong | ||
| 180 | #pragma varargck type "llx" vlong | ||
| 181 | #pragma varargck type "lld" uvlong | ||
| 182 | #pragma varargck type "llx" uvlong | ||
| 183 | #pragma varargck type "ld" long | ||
| 184 | #pragma varargck type "lx" long | ||
| 185 | #pragma varargck type "ld" ulong | ||
| 186 | #pragma varargck type "lx" ulong | ||
| 187 | #pragma varargck type "d" int | ||
| 188 | #pragma varargck type "x" int | ||
| 189 | #pragma varargck type "c" int | ||
| 190 | #pragma varargck type "C" int | ||
| 191 | #pragma varargck type "d" uint | ||
| 192 | #pragma varargck type "x" uint | ||
| 193 | #pragma varargck type "c" uint | ||
| 194 | #pragma varargck type "C" uint | ||
| 195 | #pragma varargck type "f" double | ||
| 196 | #pragma varargck type "e" double | ||
| 197 | #pragma varargck type "g" double | ||
| 198 | #pragma varargck type "s" char* | ||
| 199 | #pragma varargck type "q" char* | ||
| 200 | #pragma varargck type "S" Rune* | ||
| 201 | #pragma varargck type "Q" Rune* | ||
| 202 | #pragma varargck type "r" void | ||
| 203 | #pragma varargck type "%" void | ||
| 204 | #pragma varargck type "n" int* | ||
| 205 | #pragma varargck type "p" void* | ||
| 206 | #pragma varargck flag ',' | ||
| 207 | #pragma varargck type "<" void* | ||
| 208 | #pragma varargck type "[" void* | ||
| 209 | #pragma varargck type "H" void* | ||
| 210 | |||
| 211 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 212 | extern int dofmt(Fmt*, char*); | ||
| 213 | extern int dorfmt(Fmt*, Rune*); | ||
| 214 | extern int fmtprint(Fmt*, char*, ...); | ||
| 215 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 216 | extern int fmtrune(Fmt*, int); | ||
| 217 | extern int fmtstrcpy(Fmt*, char*); | ||
| 218 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 219 | /* | ||
| 220 | * error string for %r | ||
| 221 | * supplied on per os basis, not part of fmt library | ||
| 222 | */ | ||
| 223 | extern int errfmt(Fmt *f); | ||
| 224 | |||
| 225 | /* | ||
| 226 | * quoted strings | ||
| 227 | */ | ||
| 228 | extern char *unquotestrdup(char*); | ||
| 229 | extern Rune *unquoterunestrdup(Rune*); | ||
| 230 | extern char *quotestrdup(char*); | ||
| 231 | extern Rune *quoterunestrdup(Rune*); | ||
| 232 | extern int quotestrfmt(Fmt*); | ||
| 233 | extern int quoterunestrfmt(Fmt*); | ||
| 234 | extern void quotefmtinstall(void); | ||
| 235 | extern int (*doquote)(int); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * random number | ||
| 239 | */ | ||
| 240 | extern void srand(long); | ||
| 241 | extern int rand(void); | ||
| 242 | extern int nrand(int); | ||
| 243 | extern long lrand(void); | ||
| 244 | extern long lnrand(long); | ||
| 245 | extern double frand(void); | ||
| 246 | extern ulong truerand(void); | ||
| 247 | extern ulong ntruerand(ulong); | ||
| 248 | |||
| 249 | /* | ||
| 250 | * math | ||
| 251 | */ | ||
| 252 | extern ulong getfcr(void); | ||
| 253 | extern void setfsr(ulong); | ||
| 254 | extern ulong getfsr(void); | ||
| 255 | extern void setfcr(ulong); | ||
| 256 | extern double NaN(void); | ||
| 257 | extern double Inf(int); | ||
| 258 | extern int isNaN(double); | ||
| 259 | extern int isInf(double, int); | ||
| 260 | |||
| 261 | extern double pow(double, double); | ||
| 262 | extern double atan2(double, double); | ||
| 263 | extern double fabs(double); | ||
| 264 | extern double atan(double); | ||
| 265 | extern double log(double); | ||
| 266 | extern double log10(double); | ||
| 267 | extern double exp(double); | ||
| 268 | extern double floor(double); | ||
| 269 | extern double ceil(double); | ||
| 270 | extern double hypot(double, double); | ||
| 271 | extern double sin(double); | ||
| 272 | extern double cos(double); | ||
| 273 | extern double tan(double); | ||
| 274 | extern double asin(double); | ||
| 275 | extern double acos(double); | ||
| 276 | extern double sinh(double); | ||
| 277 | extern double cosh(double); | ||
| 278 | extern double tanh(double); | ||
| 279 | extern double sqrt(double); | ||
| 280 | extern double fmod(double, double); | ||
| 281 | |||
| 282 | #define HUGE 3.4028234e38 | ||
| 283 | #define PIO2 1.570796326794896619231e0 | ||
| 284 | #define PI (PIO2+PIO2) | ||
| 285 | |||
| 286 | /* | ||
| 287 | * Time-of-day | ||
| 288 | */ | ||
| 289 | |||
| 290 | typedef | ||
| 291 | struct Tm | ||
| 292 | { | ||
| 293 | int sec; | ||
| 294 | int min; | ||
| 295 | int hour; | ||
| 296 | int mday; | ||
| 297 | int mon; | ||
| 298 | int year; | ||
| 299 | int wday; | ||
| 300 | int yday; | ||
| 301 | char zone[4]; | ||
| 302 | int tzoff; | ||
| 303 | } Tm; | ||
| 304 | |||
| 305 | extern Tm* gmtime(long); | ||
| 306 | extern Tm* localtime(long); | ||
| 307 | extern char* asctime(Tm*); | ||
| 308 | extern char* ctime(long); | ||
| 309 | extern double cputime(void); | ||
| 310 | extern long times(long*); | ||
| 311 | extern long tm2sec(Tm*); | ||
| 312 | extern vlong nsec(void); | ||
| 313 | |||
| 314 | /* | ||
| 315 | * one-of-a-kind | ||
| 316 | */ | ||
| 317 | enum | ||
| 318 | { | ||
| 319 | PNPROC = 1, | ||
| 320 | PNGROUP = 2, | ||
| 321 | }; | ||
| 322 | |||
| 323 | extern void _assert(char*); | ||
| 324 | extern int abs(int); | ||
| 325 | extern int atexit(void(*)(void)); | ||
| 326 | extern void atexitdont(void(*)(void)); | ||
| 327 | extern int atnotify(int(*)(void*, char*), int); | ||
| 328 | extern double atof(char*); | ||
| 329 | extern int atoi(char*); | ||
| 330 | extern long atol(char*); | ||
| 331 | extern double charstod(int(*)(void*), void*); | ||
| 332 | extern char* cleanname(char*); | ||
| 333 | extern int decrypt(void*, void*, int); | ||
| 334 | extern int encrypt(void*, void*, int); | ||
| 335 | extern int dec64(uchar*, int, char*, int); | ||
| 336 | extern int enc64(char*, int, uchar*, int); | ||
| 337 | extern int dec32(uchar*, int, char*, int); | ||
| 338 | extern int enc32(char*, int, uchar*, int); | ||
| 339 | extern int dec16(uchar*, int, char*, int); | ||
| 340 | extern int enc16(char*, int, uchar*, int); | ||
| 341 | extern int encodefmt(Fmt*); | ||
| 342 | extern void exits(char*); | ||
| 343 | extern double frexp(double, int*); | ||
| 344 | extern uintptr getcallerpc(void*); | ||
| 345 | extern char* getenv(char*); | ||
| 346 | extern int getfields(char*, char**, int, int, char*); | ||
| 347 | extern char* getuser(void); | ||
| 348 | extern char* getwd(char*, int); | ||
| 349 | extern int iounit(int); | ||
| 350 | extern long labs(long); | ||
| 351 | extern double ldexp(double, int); | ||
| 352 | extern void longjmp(jmp_buf, int); | ||
| 353 | extern char* mktemp(char*); | ||
| 354 | extern double modf(double, double*); | ||
| 355 | extern int netcrypt(void*, void*); | ||
| 356 | extern void notejmp(void*, jmp_buf, int); | ||
| 357 | extern void perror(char*); | ||
| 358 | extern int postnote(int, int, char *); | ||
| 359 | extern double pow10(int); | ||
| 360 | extern double ipow10(int); | ||
| 361 | extern int putenv(char*, char*); | ||
| 362 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 363 | extern void* sbrk(ulong); | ||
| 364 | extern int setjmp(jmp_buf); | ||
| 365 | extern double strtod(char*, char**); | ||
| 366 | extern long strtol(char*, char**, int); | ||
| 367 | extern ulong strtoul(char*, char**, int); | ||
| 368 | extern vlong strtoll(char*, char**, int); | ||
| 369 | extern uvlong strtoull(char*, char**, int); | ||
| 370 | extern void sysfatal(char*, ...); | ||
| 371 | #pragma varargck argpos sysfatal 1 | ||
| 372 | extern void syslog(int, char*, char*, ...); | ||
| 373 | #pragma varargck argpos syslog 3 | ||
| 374 | extern long time(long*); | ||
| 375 | extern int tolower(int); | ||
| 376 | extern int toupper(int); | ||
| 377 | |||
| 378 | /* | ||
| 379 | * synchronization | ||
| 380 | */ | ||
| 381 | typedef | ||
| 382 | struct Lock { | ||
| 383 | int val; | ||
| 384 | } Lock; | ||
| 385 | |||
| 386 | extern int _tas(int*); | ||
| 387 | |||
| 388 | extern void lock(Lock*); | ||
| 389 | extern void unlock(Lock*); | ||
| 390 | extern int canlock(Lock*); | ||
| 391 | |||
| 392 | typedef struct QLp QLp; | ||
| 393 | struct QLp | ||
| 394 | { | ||
| 395 | int inuse; | ||
| 396 | QLp *next; | ||
| 397 | char state; | ||
| 398 | }; | ||
| 399 | |||
| 400 | typedef | ||
| 401 | struct QLock | ||
| 402 | { | ||
| 403 | Lock lock; | ||
| 404 | int locked; | ||
| 405 | QLp *head; | ||
| 406 | QLp *tail; | ||
| 407 | } QLock; | ||
| 408 | |||
| 409 | extern void qlock(QLock*); | ||
| 410 | extern void qunlock(QLock*); | ||
| 411 | extern int canqlock(QLock*); | ||
| 412 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 413 | |||
| 414 | typedef | ||
| 415 | struct RWLock | ||
| 416 | { | ||
| 417 | Lock lock; | ||
| 418 | int readers; /* number of readers */ | ||
| 419 | int writer; /* number of writers */ | ||
| 420 | QLp *head; /* list of waiting processes */ | ||
| 421 | QLp *tail; | ||
| 422 | } RWLock; | ||
| 423 | |||
| 424 | extern int canrlock(RWLock*); | ||
| 425 | extern int canwlock(RWLock*); | ||
| 426 | extern void rlock(RWLock*); | ||
| 427 | extern void runlock(RWLock*); | ||
| 428 | extern void wlock(RWLock*); | ||
| 429 | extern void wunlock(RWLock*); | ||
| 430 | |||
| 431 | extern void** privalloc(void); | ||
| 432 | extern void privfree(void**); | ||
| 433 | |||
| 434 | /* | ||
| 435 | * network dialing | ||
| 436 | */ | ||
| 437 | #define NETPATHLEN 40 | ||
| 438 | extern int accept(int, char*); | ||
| 439 | extern int announce(char*, char*); | ||
| 440 | extern int dial(char*, char*, char*, int*); | ||
| 441 | extern void setnetmtpt(char*, int, char*); | ||
| 442 | extern int hangup(int); | ||
| 443 | extern int listen(char*, char*); | ||
| 444 | extern char* netmkaddr(char*, char*, char*); | ||
| 445 | extern int reject(int, char*, char*); | ||
| 446 | |||
| 447 | /* | ||
| 448 | * system calls | ||
| 449 | * | ||
| 450 | */ | ||
| 451 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 452 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 453 | #define ERRMAX 128 /* max length of error string */ | ||
| 454 | |||
| 455 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 456 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 457 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 458 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 459 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 460 | #define MCACHE 0x0010 /* cache some data */ | ||
| 461 | #define MMASK 0x0017 /* all bits on */ | ||
| 462 | |||
| 463 | #define OREAD 0 /* open for read */ | ||
| 464 | #define OWRITE 1 /* write */ | ||
| 465 | #define ORDWR 2 /* read and write */ | ||
| 466 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 467 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 468 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 469 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 470 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 471 | |||
| 472 | #define AEXIST 0 /* accessible: exists */ | ||
| 473 | #define AEXEC 1 /* execute access */ | ||
| 474 | #define AWRITE 2 /* write access */ | ||
| 475 | #define AREAD 4 /* read access */ | ||
| 476 | |||
| 477 | |||
| 478 | /* Segattch */ | ||
| 479 | #define SG_RONLY 0040 /* read only */ | ||
| 480 | #define SG_CEXEC 0100 /* detach on exec */ | ||
| 481 | |||
| 482 | #define NCONT 0 /* continue after note */ | ||
| 483 | #define NDFLT 1 /* terminate after note */ | ||
| 484 | #define NSAVE 2 /* clear note but hold state */ | ||
| 485 | #define NRSTR 3 /* restore saved state */ | ||
| 486 | |||
| 487 | /* rfork */ | ||
| 488 | enum | ||
| 489 | { | ||
| 490 | RFNAMEG = (1<<0), | ||
| 491 | RFENVG = (1<<1), | ||
| 492 | RFFDG = (1<<2), | ||
| 493 | RFNOTEG = (1<<3), | ||
| 494 | RFPROC = (1<<4), | ||
| 495 | RFMEM = (1<<5), | ||
| 496 | RFNOWAIT = (1<<6), | ||
| 497 | RFCNAMEG = (1<<10), | ||
| 498 | RFCENVG = (1<<11), | ||
| 499 | RFCFDG = (1<<12), | ||
| 500 | RFREND = (1<<13), | ||
| 501 | RFNOMNT = (1<<14) | ||
| 502 | }; | ||
| 503 | |||
| 504 | /* bits in Qid.type */ | ||
| 505 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 506 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 507 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 508 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 509 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 510 | #define QTFILE 0x00 /* plain file */ | ||
| 511 | |||
| 512 | /* bits in Dir.mode */ | ||
| 513 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 514 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 515 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 516 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 517 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 518 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 519 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 520 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 521 | |||
| 522 | typedef | ||
| 523 | struct Qid | ||
| 524 | { | ||
| 525 | uvlong path; | ||
| 526 | ulong vers; | ||
| 527 | uchar type; | ||
| 528 | } Qid; | ||
| 529 | |||
| 530 | typedef | ||
| 531 | struct Dir { | ||
| 532 | /* system-modified data */ | ||
| 533 | ushort type; /* server type */ | ||
| 534 | uint dev; /* server subtype */ | ||
| 535 | /* file data */ | ||
| 536 | Qid qid; /* unique id from server */ | ||
| 537 | ulong mode; /* permissions */ | ||
| 538 | ulong atime; /* last read time */ | ||
| 539 | ulong mtime; /* last write time */ | ||
| 540 | vlong length; /* file length */ | ||
| 541 | char *name; /* last element of path */ | ||
| 542 | char *uid; /* owner name */ | ||
| 543 | char *gid; /* group name */ | ||
| 544 | char *muid; /* last modifier name */ | ||
| 545 | } Dir; | ||
| 546 | |||
| 547 | extern Dir* dirstat(char*); | ||
| 548 | extern Dir* dirfstat(int); | ||
| 549 | extern int dirwstat(char*, Dir*); | ||
| 550 | extern int dirfwstat(int, Dir*); | ||
| 551 | extern long dirread(int, Dir**); | ||
| 552 | extern void nulldir(Dir*); | ||
| 553 | extern long dirreadall(int, Dir**); | ||
| 554 | |||
| 555 | typedef | ||
| 556 | struct Waitmsg | ||
| 557 | { | ||
| 558 | int pid; /* of loved one */ | ||
| 559 | ulong time[3]; /* of loved one & descendants */ | ||
| 560 | char *msg; | ||
| 561 | } Waitmsg; | ||
| 562 | |||
| 563 | typedef | ||
| 564 | struct IOchunk | ||
| 565 | { | ||
| 566 | void *addr; | ||
| 567 | ulong len; | ||
| 568 | } IOchunk; | ||
| 569 | |||
| 570 | extern void _exits(char*); | ||
| 571 | |||
| 572 | extern void abort(void); | ||
| 573 | extern int access(char*, int); | ||
| 574 | extern long alarm(ulong); | ||
| 575 | extern int await(char*, int); | ||
| 576 | extern int bind(char*, char*, int); | ||
| 577 | extern int brk(void*); | ||
| 578 | extern int chdir(char*); | ||
| 579 | extern int close(int); | ||
| 580 | extern int create(char*, int, ulong); | ||
| 581 | extern int dup(int, int); | ||
| 582 | extern int errstr(char*, uint); | ||
| 583 | extern int exec(char*, char*[]); | ||
| 584 | extern int execl(char*, ...); | ||
| 585 | extern int fork(void); | ||
| 586 | extern int rfork(int); | ||
| 587 | extern int fauth(int, char*); | ||
| 588 | extern int fstat(int, uchar*, int); | ||
| 589 | extern int fwstat(int, uchar*, int); | ||
| 590 | extern int fversion(int, int, char*, int); | ||
| 591 | extern int mount(int, int, char*, int, char*); | ||
| 592 | extern int unmount(char*, char*); | ||
| 593 | extern int noted(int); | ||
| 594 | extern int notify(void(*)(void*, char*)); | ||
| 595 | extern int open(char*, int); | ||
| 596 | extern int fd2path(int, char*, int); | ||
| 597 | extern int pipe(int*); | ||
| 598 | extern long pread(int, void*, long, vlong); | ||
| 599 | extern long preadv(int, IOchunk*, int, vlong); | ||
| 600 | extern long pwrite(int, void*, long, vlong); | ||
| 601 | extern long pwritev(int, IOchunk*, int, vlong); | ||
| 602 | extern long read(int, void*, long); | ||
| 603 | extern long readn(int, void*, long); | ||
| 604 | extern long readv(int, IOchunk*, int); | ||
| 605 | extern int remove(char*); | ||
| 606 | extern void* sbrk(ulong); | ||
| 607 | extern long oseek(int, long, int); | ||
| 608 | extern vlong seek(int, vlong, int); | ||
| 609 | extern long segattach(int, char*, void*, ulong); | ||
| 610 | extern int segbrk(void*, void*); | ||
| 611 | extern int segdetach(void*); | ||
| 612 | extern int segflush(void*, ulong); | ||
| 613 | extern int segfree(void*, ulong); | ||
| 614 | extern int sleep(long); | ||
| 615 | extern int stat(char*, uchar*, int); | ||
| 616 | extern Waitmsg* wait(void); | ||
| 617 | extern int waitpid(void); | ||
| 618 | extern long write(int, void*, long); | ||
| 619 | extern long writev(int, IOchunk*, int); | ||
| 620 | extern int wstat(char*, uchar*, int); | ||
| 621 | extern void* rendezvous(void*, void*); | ||
| 622 | |||
| 623 | extern int getpid(void); | ||
| 624 | extern int getppid(void); | ||
| 625 | extern void rerrstr(char*, uint); | ||
| 626 | extern char* sysname(void); | ||
| 627 | extern void werrstr(char*, ...); | ||
| 628 | #pragma varargck argpos werrstr 1 | ||
| 629 | |||
| 630 | extern char *argv0; | ||
| 631 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 632 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 633 | argc--, argv++) {\ | ||
| 634 | char *_args, *_argt;\ | ||
| 635 | Rune _argc;\ | ||
| 636 | _args = &argv[0][1];\ | ||
| 637 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 638 | argc--; argv++; break;\ | ||
| 639 | }\ | ||
| 640 | _argc = 0;\ | ||
| 641 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 642 | switch(_argc) | ||
| 643 | #define ARGEND SET(_argt);USED(_argt,_argc,_args);}USED(argv, argc); | ||
| 644 | #define ARGF() (_argt=_args, _args="",\ | ||
| 645 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 646 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 647 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 648 | |||
| 649 | #define ARGC() _argc | ||
| 650 | |||
| 651 | /* | ||
| 652 | * Extensions for Inferno to basic libc.h | ||
| 653 | */ | ||
| 654 | |||
| 655 | #define setbinmode() | ||
| 656 | #undef __LITTLE_ENDIAN | ||
| 657 | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | /* | ||
| 2 | * Solaris 2.5/sparc | ||
| 3 | */ | ||
| 4 | |||
| 5 | /* | ||
| 6 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 7 | */ | ||
| 8 | typedef struct FPU FPU; | ||
| 9 | struct FPU | ||
| 10 | { | ||
| 11 | ulong fsr; | ||
| 12 | }; | ||
| 13 | |||
| 14 | extern Proc *getup(); | ||
| 15 | #define up (getup()) | ||
| 16 | |||
| 17 | #define BIGEND | ||
| @@ -0,0 +1,64 @@ | |||
| 1 | #define nil ((void*)0) | ||
| 2 | typedef unsigned short ushort; | ||
| 3 | typedef unsigned char uchar; | ||
| 4 | typedef unsigned long ulong; | ||
| 5 | typedef unsigned int uint; | ||
| 6 | typedef signed char schar; | ||
| 7 | typedef long long vlong; | ||
| 8 | typedef unsigned long long uvlong; | ||
| 9 | typedef unsigned long uintptr; | ||
| 10 | typedef ushort Rune; | ||
| 11 | typedef union FPdbleword FPdbleword; | ||
| 12 | typedef long jmp_buf[2]; | ||
| 13 | #define JMPBUFSP 0 | ||
| 14 | #define JMPBUFPC 1 | ||
| 15 | #define JMPBUFDPC (-8) | ||
| 16 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 17 | typedef unsigned char u8int; | ||
| 18 | typedef unsigned short u16int; | ||
| 19 | typedef unsigned int u32int; | ||
| 20 | typedef unsigned long long u64int; | ||
| 21 | |||
| 22 | /* FCR */ | ||
| 23 | #define FPINEX (1<<23) | ||
| 24 | #define FPOVFL (1<<26) | ||
| 25 | #define FPUNFL (1<<25) | ||
| 26 | #define FPZDIV (1<<24) | ||
| 27 | #define FPRNR (0<<30) | ||
| 28 | #define FPRZ (1<<30) | ||
| 29 | #define FPINVAL (1<<27) | ||
| 30 | #define FPRPINF (2<<30) | ||
| 31 | #define FPRNINF (3<<30) | ||
| 32 | #define FPRMASK (3<<30) | ||
| 33 | #define FPPEXT 0 | ||
| 34 | #define FPPSGL 0 | ||
| 35 | #define FPPDBL 0 | ||
| 36 | #define FPPMASK 0 | ||
| 37 | /* FSR */ | ||
| 38 | #define FPAINEX (1<<5) | ||
| 39 | #define FPAZDIV (1<<6) | ||
| 40 | #define FPAUNFL (1<<7) | ||
| 41 | #define FPAOVFL (1<<8) | ||
| 42 | #define FPAINVAL (1<<9) | ||
| 43 | union FPdbleword | ||
| 44 | { | ||
| 45 | double x; | ||
| 46 | struct { /* big endian */ | ||
| 47 | ulong hi; | ||
| 48 | ulong lo; | ||
| 49 | }; | ||
| 50 | }; | ||
| 51 | |||
| 52 | typedef char* va_list; | ||
| 53 | #define va_start(list, start) list =\ | ||
| 54 | (sizeof(start) < 4?\ | ||
| 55 | (char*)((int*)&(start)+1):\ | ||
| 56 | (char*)(&(start)+1)) | ||
| 57 | #define va_end(list)\ | ||
| 58 | USED(list) | ||
| 59 | #define va_arg(list, mode)\ | ||
| 60 | ((sizeof(mode) == 1)?\ | ||
| 61 | ((mode*)(list += 4))[-1]:\ | ||
| 62 | (sizeof(mode) == 2)?\ | ||
| 63 | ((mode*)(list += 4))[-1]:\ | ||
| 64 | ((mode*)(list += sizeof(mode)))[-1]) | ||
| @@ -0,0 +1,11 @@ | |||
| 1 | This subversion distribution contains the Inferno distribution trees starting with 20060303 EXCLUDING | ||
| 2 | derived executable files in the per-platform bin directories (except for those needed | ||
| 3 | on a given platform to build anything, such as mk or yacc). It also EXCLUDES any non-Free | ||
| 4 | components, mainly the Bigelow & Holmes fonts, which can be obtained from the primary | ||
| 5 | Inferno distribution. Since the fonts hardly ever change, you need only do that once. | ||
| 6 | The /dis files are also derived, of course, but they are included; | ||
| 7 | the extra space is modest these days, and it helps support some regression testing. | ||
| 8 | |||
| 9 | The overall licence is GPLv2, to accord with Google understandable limitation to one licence, | ||
| 10 | since GPLv2 arguably imposes most constraints on redistribution (of the set we use in the full distribution), | ||
| 11 | but where less restrictive licence is available, and could be used, that is noted in a NOTICE file. | ||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc* getup(void); | ||
| 8 | #define up (getup()) | ||
| 9 | |||
| 10 | /* | ||
| 11 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 12 | */ | ||
| 13 | typedef struct FPU FPU; | ||
| 14 | struct FPU | ||
| 15 | { | ||
| 16 | uchar env[28]; | ||
| 17 | }; | ||
| 18 | |||
| 19 | typedef sigjmp_buf osjmpbuf; | ||
| 20 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| 21 | |||
| @@ -0,0 +1,393 @@ | |||
| 1 | #define _POSIX_SOURCE | ||
| 2 | #define _POSIX_C_SOURCE 1 | ||
| 3 | #define _LARGEFILE64_SOURCE 1 | ||
| 4 | #define _FILE_OFFSET_BITS 64 | ||
| 5 | #include <stdlib.h> | ||
| 6 | #include <stdarg.h> | ||
| 7 | #include <errno.h> | ||
| 8 | #include <string.h> | ||
| 9 | #include "math.h" | ||
| 10 | #include <fcntl.h> | ||
| 11 | #include <setjmp.h> | ||
| 12 | #include <float.h> | ||
| 13 | |||
| 14 | #define getwd infgetwd | ||
| 15 | |||
| 16 | /* | ||
| 17 | * math/dtoa.c | ||
| 18 | */ | ||
| 19 | #define __LITTLE_ENDIAN | ||
| 20 | |||
| 21 | #define nil ((void*)0) | ||
| 22 | |||
| 23 | typedef unsigned char uchar; | ||
| 24 | typedef unsigned int uint; | ||
| 25 | typedef unsigned long ulong; | ||
| 26 | typedef signed char schar; | ||
| 27 | typedef unsigned short ushort; | ||
| 28 | typedef unsigned short Rune; | ||
| 29 | typedef long long int vlong; | ||
| 30 | typedef unsigned long long int uvlong; | ||
| 31 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 32 | typedef unsigned short u16int; | ||
| 33 | typedef unsigned char u8int; | ||
| 34 | typedef unsigned long uintptr; | ||
| 35 | |||
| 36 | typedef signed char int8; | ||
| 37 | typedef unsigned char uint8; | ||
| 38 | typedef short int16; | ||
| 39 | typedef unsigned short uint16; | ||
| 40 | typedef int int32; | ||
| 41 | typedef unsigned int uint32; | ||
| 42 | typedef long long int64; | ||
| 43 | typedef unsigned long long uint64; | ||
| 44 | |||
| 45 | #define USED(x) if(x);else | ||
| 46 | #define SET(x) | ||
| 47 | |||
| 48 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 49 | |||
| 50 | /* | ||
| 51 | * mem and string routines are declared by ANSI/POSIX files above | ||
| 52 | */ | ||
| 53 | |||
| 54 | enum | ||
| 55 | { | ||
| 56 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 57 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 58 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 59 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 60 | }; | ||
| 61 | |||
| 62 | /* | ||
| 63 | * rune routines | ||
| 64 | */ | ||
| 65 | extern int runetochar(char*, Rune*); | ||
| 66 | extern int chartorune(Rune*, char*); | ||
| 67 | extern int runelen(long); | ||
| 68 | extern int runenlen(Rune*, int); | ||
| 69 | extern int fullrune(char*, int); | ||
| 70 | extern int utflen(char*); | ||
| 71 | extern int utfnlen(char*, long); | ||
| 72 | extern char* utfrune(char*, long); | ||
| 73 | extern char* utfrrune(char*, long); | ||
| 74 | extern char* utfutf(char*, char*); | ||
| 75 | extern char* utfecpy(char*, char*, char*); | ||
| 76 | |||
| 77 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 78 | extern Rune* runestrchr(Rune*, Rune); | ||
| 79 | extern int runestrcmp(Rune*, Rune*); | ||
| 80 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 81 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 82 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 83 | extern Rune* runestrdup(Rune*); | ||
| 84 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 85 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 86 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 87 | extern long runestrlen(Rune*); | ||
| 88 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 89 | |||
| 90 | extern Rune tolowerrune(Rune); | ||
| 91 | extern Rune totitlerune(Rune); | ||
| 92 | extern Rune toupperrune(Rune); | ||
| 93 | extern int isalpharune(Rune); | ||
| 94 | extern int islowerrune(Rune); | ||
| 95 | extern int isspacerune(Rune); | ||
| 96 | extern int istitlerune(Rune); | ||
| 97 | extern int isupperrune(Rune); | ||
| 98 | |||
| 99 | /* | ||
| 100 | * malloc | ||
| 101 | */ | ||
| 102 | extern void* malloc(size_t); | ||
| 103 | extern void* mallocz(ulong, int); | ||
| 104 | extern void free(void*); | ||
| 105 | extern ulong msize(void*); | ||
| 106 | extern void* calloc(size_t, size_t); | ||
| 107 | extern void* realloc(void*, size_t); | ||
| 108 | extern void setmalloctag(void*, ulong); | ||
| 109 | extern void setrealloctag(void*, ulong); | ||
| 110 | extern ulong getmalloctag(void*); | ||
| 111 | extern ulong getrealloctag(void*); | ||
| 112 | extern void* malloctopoolblock(void*); | ||
| 113 | |||
| 114 | extern int getfields(char*, char**, int, int, char*); | ||
| 115 | extern uintptr getcallerpc(void*); | ||
| 116 | |||
| 117 | /* | ||
| 118 | * print routines | ||
| 119 | */ | ||
| 120 | typedef struct Fmt Fmt; | ||
| 121 | struct Fmt{ | ||
| 122 | uchar runes; /* output buffer is runes or chars? */ | ||
| 123 | void *start; /* of buffer */ | ||
| 124 | void *to; /* current place in the buffer */ | ||
| 125 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 126 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 127 | void *farg; /* to make flush a closure */ | ||
| 128 | int nfmt; /* num chars formatted so far */ | ||
| 129 | va_list args; /* args passed to dofmt */ | ||
| 130 | int r; /* % format Rune */ | ||
| 131 | int width; | ||
| 132 | int prec; | ||
| 133 | ulong flags; | ||
| 134 | }; | ||
| 135 | |||
| 136 | enum{ | ||
| 137 | FmtWidth = 1, | ||
| 138 | FmtLeft = FmtWidth << 1, | ||
| 139 | FmtPrec = FmtLeft << 1, | ||
| 140 | FmtSharp = FmtPrec << 1, | ||
| 141 | FmtSpace = FmtSharp << 1, | ||
| 142 | FmtSign = FmtSpace << 1, | ||
| 143 | FmtZero = FmtSign << 1, | ||
| 144 | FmtUnsigned = FmtZero << 1, | ||
| 145 | FmtShort = FmtUnsigned << 1, | ||
| 146 | FmtLong = FmtShort << 1, | ||
| 147 | FmtVLong = FmtLong << 1, | ||
| 148 | FmtComma = FmtVLong << 1, | ||
| 149 | FmtByte = FmtComma << 1, | ||
| 150 | |||
| 151 | FmtFlag = FmtByte << 1 | ||
| 152 | }; | ||
| 153 | |||
| 154 | extern int print(char*, ...); | ||
| 155 | extern char* seprint(char*, char*, char*, ...); | ||
| 156 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 157 | extern int snprint(char*, int, char*, ...); | ||
| 158 | extern int vsnprint(char*, int, char*, va_list); | ||
| 159 | extern char* smprint(char*, ...); | ||
| 160 | extern char* vsmprint(char*, va_list); | ||
| 161 | extern int sprint(char*, char*, ...); | ||
| 162 | extern int fprint(int, char*, ...); | ||
| 163 | extern int vfprint(int, char*, va_list); | ||
| 164 | |||
| 165 | extern int runesprint(Rune*, char*, ...); | ||
| 166 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 167 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 168 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 169 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 170 | extern Rune* runesmprint(char*, ...); | ||
| 171 | extern Rune* runevsmprint(char*, va_list); | ||
| 172 | |||
| 173 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 174 | extern int fmtfdflush(Fmt*); | ||
| 175 | extern int fmtstrinit(Fmt*); | ||
| 176 | extern char* fmtstrflush(Fmt*); | ||
| 177 | extern int runefmtstrinit(Fmt*); | ||
| 178 | extern Rune* runefmtstrflush(Fmt*); | ||
| 179 | |||
| 180 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 181 | extern int dofmt(Fmt*, char*); | ||
| 182 | extern int dorfmt(Fmt*, Rune*); | ||
| 183 | extern int fmtprint(Fmt*, char*, ...); | ||
| 184 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 185 | extern int fmtrune(Fmt*, int); | ||
| 186 | extern int fmtstrcpy(Fmt*, char*); | ||
| 187 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 188 | /* | ||
| 189 | * error string for %r | ||
| 190 | * supplied on per os basis, not part of fmt library | ||
| 191 | */ | ||
| 192 | extern int errfmt(Fmt *f); | ||
| 193 | |||
| 194 | /* | ||
| 195 | * quoted strings | ||
| 196 | */ | ||
| 197 | extern char *unquotestrdup(char*); | ||
| 198 | extern Rune *unquoterunestrdup(Rune*); | ||
| 199 | extern char *quotestrdup(char*); | ||
| 200 | extern Rune *quoterunestrdup(Rune*); | ||
| 201 | extern int quotestrfmt(Fmt*); | ||
| 202 | extern int quoterunestrfmt(Fmt*); | ||
| 203 | extern void quotefmtinstall(void); | ||
| 204 | extern int (*doquote)(int); | ||
| 205 | |||
| 206 | extern char* strdup(const char*); | ||
| 207 | extern int tokenize(char*, char**, int); | ||
| 208 | extern vlong strtoll(const char*, char**, int); | ||
| 209 | #define qsort infqsort | ||
| 210 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 211 | |||
| 212 | extern int isNaN(double); | ||
| 213 | extern int isInf(double, int); | ||
| 214 | |||
| 215 | /* | ||
| 216 | * Time-of-day | ||
| 217 | */ | ||
| 218 | |||
| 219 | typedef struct Tm Tm; | ||
| 220 | struct Tm { | ||
| 221 | int sec; | ||
| 222 | int min; | ||
| 223 | int hour; | ||
| 224 | int mday; | ||
| 225 | int mon; | ||
| 226 | int year; | ||
| 227 | int wday; | ||
| 228 | int yday; | ||
| 229 | char zone[4]; | ||
| 230 | }; | ||
| 231 | |||
| 232 | /* | ||
| 233 | * one-of-a-kind | ||
| 234 | */ | ||
| 235 | extern int getfields(char*, char**, int, int, char*); | ||
| 236 | extern char* getuser(void); | ||
| 237 | extern char* getwd(char*, int); | ||
| 238 | extern double pow10(int); | ||
| 239 | extern double ipow10(int); | ||
| 240 | extern vlong strtoll(const char*, char**, int); | ||
| 241 | extern uvlong strtoull(const char*, char**, int); | ||
| 242 | extern void sysfatal(char*, ...); | ||
| 243 | extern int dec64(uchar*, int, char*, int); | ||
| 244 | extern int enc64(char*, int, uchar*, int); | ||
| 245 | extern int dec32(uchar*, int, char*, int); | ||
| 246 | extern int enc32(char*, int, uchar*, int); | ||
| 247 | extern int dec16(uchar*, int, char*, int); | ||
| 248 | extern int enc16(char*, int, uchar*, int); | ||
| 249 | extern int encodefmt(Fmt*); | ||
| 250 | |||
| 251 | /* | ||
| 252 | * synchronization | ||
| 253 | */ | ||
| 254 | typedef | ||
| 255 | struct Lock { | ||
| 256 | int val; | ||
| 257 | int pid; | ||
| 258 | } Lock; | ||
| 259 | |||
| 260 | extern int _tas(int*); | ||
| 261 | |||
| 262 | extern void lock(Lock*); | ||
| 263 | extern void unlock(Lock*); | ||
| 264 | extern int canlock(Lock*); | ||
| 265 | |||
| 266 | typedef struct QLock QLock; | ||
| 267 | struct QLock | ||
| 268 | { | ||
| 269 | Lock use; /* to access Qlock structure */ | ||
| 270 | Proc *head; /* next process waiting for object */ | ||
| 271 | Proc *tail; /* last process waiting for object */ | ||
| 272 | int locked; /* flag */ | ||
| 273 | }; | ||
| 274 | |||
| 275 | extern void qlock(QLock*); | ||
| 276 | extern void qunlock(QLock*); | ||
| 277 | extern int canqlock(QLock*); | ||
| 278 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 279 | |||
| 280 | typedef | ||
| 281 | struct RWLock | ||
| 282 | { | ||
| 283 | Lock l; /* Lock modify lock */ | ||
| 284 | QLock x; /* Mutual exclusion lock */ | ||
| 285 | QLock k; /* Lock for waiting writers */ | ||
| 286 | int readers; /* Count of readers in lock */ | ||
| 287 | } RWLock; | ||
| 288 | |||
| 289 | extern int canrlock(RWLock*); | ||
| 290 | extern int canwlock(RWLock*); | ||
| 291 | extern void rlock(RWLock*); | ||
| 292 | extern void runlock(RWLock*); | ||
| 293 | extern void wlock(RWLock*); | ||
| 294 | extern void wunlock(RWLock*); | ||
| 295 | |||
| 296 | /* | ||
| 297 | * system calls | ||
| 298 | * | ||
| 299 | */ | ||
| 300 | enum | ||
| 301 | { | ||
| 302 | NAMELEN = 28, | ||
| 303 | ERRLEN = 64, | ||
| 304 | ERRMAX = 128, | ||
| 305 | DIRLEN = 116 | ||
| 306 | }; | ||
| 307 | |||
| 308 | #define CHDIR 0x80000000 /* mode bit for directories */ | ||
| 309 | #define CHAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 310 | #define CHEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 311 | #define CHMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 312 | #define CHREAD 0x4 /* mode bit for read permission */ | ||
| 313 | #define CHWRITE 0x2 /* mode bit for write permission */ | ||
| 314 | #define CHEXEC 0x1 /* mode bit for execute permission */ | ||
| 315 | |||
| 316 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 317 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 318 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 319 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 320 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 321 | #define MCACHE 0x0010 /* cache some data */ | ||
| 322 | #define MMASK 0x0007 /* all bits on */ | ||
| 323 | |||
| 324 | #define OREAD 0 /* open for read */ | ||
| 325 | #define OWRITE 1 /* write */ | ||
| 326 | #define ORDWR 2 /* read and write */ | ||
| 327 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 328 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 329 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 330 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 331 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 332 | |||
| 333 | typedef | ||
| 334 | struct Qid | ||
| 335 | { | ||
| 336 | ulong path; | ||
| 337 | ulong vers; | ||
| 338 | } Qid; | ||
| 339 | |||
| 340 | typedef | ||
| 341 | struct Dir | ||
| 342 | { | ||
| 343 | char name[NAMELEN]; | ||
| 344 | char uid[NAMELEN]; | ||
| 345 | char gid[NAMELEN]; | ||
| 346 | Qid qid; | ||
| 347 | ulong mode; | ||
| 348 | int atime; | ||
| 349 | int mtime; | ||
| 350 | vlong length; | ||
| 351 | ushort type; | ||
| 352 | ushort dev; | ||
| 353 | } Dir; | ||
| 354 | |||
| 355 | extern int dirfstat(int, Dir*); | ||
| 356 | extern int dirstat(char*, Dir*); | ||
| 357 | extern int dirfwstat(int, Dir*); | ||
| 358 | extern int dirwstat(char*, Dir*); | ||
| 359 | |||
| 360 | extern char* cleanname(char*); | ||
| 361 | extern void exits(char*); | ||
| 362 | extern void _exits(char*); | ||
| 363 | extern int create(char*, int, int); | ||
| 364 | |||
| 365 | extern char* getuser(void); | ||
| 366 | extern char* getwd(char*, int); | ||
| 367 | |||
| 368 | extern int errstr(char*, uint); | ||
| 369 | extern void werrstr(char*, ...); | ||
| 370 | |||
| 371 | #define ARGBEGIN for(argv++,argc--;\ | ||
| 372 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 373 | argc--, argv++) {\ | ||
| 374 | char *_args, *_argt;\ | ||
| 375 | char _argc;\ | ||
| 376 | _args = &argv[0][1];\ | ||
| 377 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 378 | argc--; argv++; break;\ | ||
| 379 | }\ | ||
| 380 | _argc = 0;\ | ||
| 381 | while((_argc = *_args++)!='\0')\ | ||
| 382 | switch(_argc) | ||
| 383 | #define ARGEND } | ||
| 384 | #define ARGF() (_argt=_args, _args="",\ | ||
| 385 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 386 | #define ARGC() _argc | ||
| 387 | |||
| 388 | /* | ||
| 389 | * Extensions for Inferno to basic libc.h | ||
| 390 | */ | ||
| 391 | |||
| 392 | #define setbinmode() | ||
| 393 | |||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,21 @@ | |||
| 1 | /* | ||
| 2 | * system- and machine-specific declarations for emu: | ||
| 3 | * floating-point save and restore, signal handling primitive, and | ||
| 4 | * implementation of the current-process variable `up'. | ||
| 5 | */ | ||
| 6 | |||
| 7 | extern Proc* getup(void); | ||
| 8 | #define up (getup()) | ||
| 9 | |||
| 10 | /* | ||
| 11 | * This structure must agree with FPsave and FPrestore asm routines | ||
| 12 | */ | ||
| 13 | typedef struct FPU FPU; | ||
| 14 | struct FPU | ||
| 15 | { | ||
| 16 | ulong fsr; | ||
| 17 | }; | ||
| 18 | |||
| 19 | typedef sigjmp_buf osjmpbuf; | ||
| 20 | #define ossetjmp(buf) sigsetjmp(buf, 1) | ||
| 21 | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* This code is a little awkward. If somebody who understands Solaris | ||
| 2 | better would tell me an idiomatic way to invoke equivalent | ||
| 3 | behavior, I'd be grateful. ehg@bell-labs.com */ | ||
| 4 | |||
| 5 | /* | ||
| 6 | * accrued exception bits in the fsr | ||
| 7 | */ | ||
| 8 | #define FPAINEX (1<<5) | ||
| 9 | #define FPAOVFL (1<<8) | ||
| 10 | #define FPAUNFL (1<<7) | ||
| 11 | #define FPAZDIV (1<<6) | ||
| 12 | #define FPAINVAL (1<<9) | ||
| 13 | |||
| 14 | /* | ||
| 15 | * exception enable bits in the fsr | ||
| 16 | */ | ||
| 17 | #define FPINEX (1<<23) | ||
| 18 | #define FPOVFL (1<<26) | ||
| 19 | #define FPUNFL (1<<25) | ||
| 20 | #define FPZDIV (1<<24) | ||
| 21 | #define FPINVAL (1<<27) | ||
| 22 | |||
| 23 | /* | ||
| 24 | * rounding | ||
| 25 | */ | ||
| 26 | #define FPRMASK (3<<30) | ||
| 27 | #define FPRNR (0<<30) | ||
| 28 | #define FPRNINF (3<<30) | ||
| 29 | #define FPRPINF (2<<30) | ||
| 30 | #define FPRZ (1<<30) | ||
| 31 | |||
| 32 | /* | ||
| 33 | * precision | ||
| 34 | */ | ||
| 35 | #define FPPDBL 0 | ||
| 36 | |||
| 37 | #define FPFCR (FPRMASK|FPINEX|FPOVFL|FPUNFL|FPZDIV|FPINVAL) | ||
| 38 | #define FPFSR (FPAINEX|FPAOVFL|FPAUNFL|FPAZDIV|FPAINVAL) | ||
| 39 | |||
| 40 | static ulong | ||
| 41 | getfcr(void) | ||
| 42 | { | ||
| 43 | ulong v; | ||
| 44 | |||
| 45 | asm(" st %fsr, [%fp-8]"); | ||
| 46 | return v; | ||
| 47 | } | ||
| 48 | |||
| 49 | static void | ||
| 50 | setfcr(ulong v) | ||
| 51 | { | ||
| 52 | ulong vv; | ||
| 53 | |||
| 54 | vv = (getfcr() & ~FPFCR) | (v & FPFCR); | ||
| 55 | asm(" ld [%fp-4], %fsr"); | ||
| 56 | } | ||
| 57 | |||
| 58 | static ulong | ||
| 59 | getfsr(void) | ||
| 60 | { | ||
| 61 | ulong v; | ||
| 62 | |||
| 63 | asm(" st %fsr, [%fp-8]"); | ||
| 64 | return v; | ||
| 65 | } | ||
| 66 | |||
| 67 | static void | ||
| 68 | setfsr(ulong v) | ||
| 69 | { | ||
| 70 | ulong vv; | ||
| 71 | |||
| 72 | vv = (getfsr() & ~FPFSR) | (v & FPFSR); | ||
| 73 | asm(" ld [%fp-4], %fsr"); | ||
| 74 | } | ||
| 75 | |||
| @@ -0,0 +1,468 @@ | |||
| 1 | #define _POSIX_SOURCE | ||
| 2 | #define _POSIX_C_SOURCE 1 | ||
| 3 | #define _LARGEFILE64_SOURCE 1 | ||
| 4 | #define _FILE_OFFSET_BITS 64 | ||
| 5 | #include <sys/types.h> | ||
| 6 | #include <stdlib.h> | ||
| 7 | #include <stdarg.h> | ||
| 8 | #define __EXTENSIONS__ | ||
| 9 | #include <unistd.h> | ||
| 10 | #undef __EXTENSIONS__ | ||
| 11 | #include <errno.h> | ||
| 12 | #include <string.h> | ||
| 13 | #include "math.h" | ||
| 14 | #include <fcntl.h> | ||
| 15 | #include <setjmp.h> | ||
| 16 | #include <float.h> | ||
| 17 | #include <time.h> | ||
| 18 | |||
| 19 | #define getwd infgetwd | ||
| 20 | |||
| 21 | #ifndef EMU | ||
| 22 | typedef struct Proc Proc; | ||
| 23 | #endif | ||
| 24 | |||
| 25 | #define nil ((void*)0) | ||
| 26 | |||
| 27 | typedef unsigned char uchar; | ||
| 28 | typedef unsigned int uint; | ||
| 29 | typedef unsigned long ulong; | ||
| 30 | typedef signed char schar; | ||
| 31 | typedef unsigned short ushort; | ||
| 32 | typedef unsigned short Rune; | ||
| 33 | typedef long long int vlong; | ||
| 34 | typedef unsigned long long int uvlong; | ||
| 35 | typedef unsigned int u32int; | ||
| 36 | typedef uvlong u64int; | ||
| 37 | |||
| 38 | typedef unsigned int mpdigit; /* for /sys/include/mp.h */ | ||
| 39 | typedef unsigned short u16int; | ||
| 40 | typedef unsigned char u8int; | ||
| 41 | typedef unsigned long uintptr; | ||
| 42 | |||
| 43 | typedef signed char int8; | ||
| 44 | typedef unsigned char uint8; | ||
| 45 | typedef short int16; | ||
| 46 | typedef unsigned short uint16; | ||
| 47 | typedef int int32; | ||
| 48 | typedef unsigned int uint32; | ||
| 49 | typedef long long int64; | ||
| 50 | typedef unsigned long long uint64; | ||
| 51 | |||
| 52 | #define USED(x) if(x){}else{} | ||
| 53 | #define SET(x) | ||
| 54 | |||
| 55 | #undef nelem | ||
| 56 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) | ||
| 57 | #undef offsetof | ||
| 58 | #define offsetof(s, m) (ulong)(&(((s*)0)->m)) | ||
| 59 | #undef assert | ||
| 60 | #define assert(x) if(x){}else _assert("x") | ||
| 61 | |||
| 62 | /* | ||
| 63 | * most mem and string routines are declared by ANSI/POSIX files above | ||
| 64 | */ | ||
| 65 | |||
| 66 | extern char* strecpy(char*, char*, char*); | ||
| 67 | extern char* strdup(const char*); | ||
| 68 | extern int cistrncmp(char*, char*, int); | ||
| 69 | extern int cistrcmp(char*, char*); | ||
| 70 | extern char* cistrstr(char*, char*); | ||
| 71 | extern int tokenize(char*, char**, int); | ||
| 72 | |||
| 73 | enum | ||
| 74 | { | ||
| 75 | UTFmax = 3, /* maximum bytes per rune */ | ||
| 76 | Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */ | ||
| 77 | Runeself = 0x80, /* rune and UTF sequences are the same (<) */ | ||
| 78 | Runeerror = 0x80 /* decoding error in UTF */ | ||
| 79 | }; | ||
| 80 | |||
| 81 | /* | ||
| 82 | * rune routines | ||
| 83 | */ | ||
| 84 | extern int runetochar(char*, Rune*); | ||
| 85 | extern int chartorune(Rune*, char*); | ||
| 86 | extern int runelen(long); | ||
| 87 | extern int runenlen(Rune*, int); | ||
| 88 | extern int fullrune(char*, int); | ||
| 89 | extern int utflen(char*); | ||
| 90 | extern int utfnlen(char*, long); | ||
| 91 | extern char* utfrune(char*, long); | ||
| 92 | extern char* utfrrune(char*, long); | ||
| 93 | extern char* utfutf(char*, char*); | ||
| 94 | extern char* utfecpy(char*, char*, char*); | ||
| 95 | |||
| 96 | extern Rune* runestrcat(Rune*, Rune*); | ||
| 97 | extern Rune* runestrchr(Rune*, Rune); | ||
| 98 | extern int runestrcmp(Rune*, Rune*); | ||
| 99 | extern Rune* runestrcpy(Rune*, Rune*); | ||
| 100 | extern Rune* runestrncpy(Rune*, Rune*, long); | ||
| 101 | extern Rune* runestrecpy(Rune*, Rune*, Rune*); | ||
| 102 | extern Rune* runestrdup(Rune*); | ||
| 103 | extern Rune* runestrncat(Rune*, Rune*, long); | ||
| 104 | extern int runestrncmp(Rune*, Rune*, long); | ||
| 105 | extern Rune* runestrrchr(Rune*, Rune); | ||
| 106 | extern long runestrlen(Rune*); | ||
| 107 | extern Rune* runestrstr(Rune*, Rune*); | ||
| 108 | |||
| 109 | extern Rune tolowerrune(Rune); | ||
| 110 | extern Rune totitlerune(Rune); | ||
| 111 | extern Rune toupperrune(Rune); | ||
| 112 | extern int isalpharune(Rune); | ||
| 113 | extern int islowerrune(Rune); | ||
| 114 | extern int isspacerune(Rune); | ||
| 115 | extern int istitlerune(Rune); | ||
| 116 | extern int isupperrune(Rune); | ||
| 117 | |||
| 118 | /* | ||
| 119 | * malloc | ||
| 120 | */ | ||
| 121 | extern void* malloc(size_t); | ||
| 122 | extern void* mallocz(ulong, int); | ||
| 123 | extern void free(void*); | ||
| 124 | extern ulong msize(void*); | ||
| 125 | extern void* calloc(size_t, size_t); | ||
| 126 | extern void* realloc(void*, size_t); | ||
| 127 | extern void setmalloctag(void*, ulong); | ||
| 128 | extern void setrealloctag(void*, ulong); | ||
| 129 | extern ulong getmalloctag(void*); | ||
| 130 | extern ulong getrealloctag(void*); | ||
| 131 | extern void* malloctopoolblock(void*); | ||
| 132 | |||
| 133 | /* | ||
| 134 | * print routines | ||
| 135 | */ | ||
| 136 | typedef struct Fmt Fmt; | ||
| 137 | struct Fmt{ | ||
| 138 | uchar runes; /* output buffer is runes or chars? */ | ||
| 139 | void *start; /* of buffer */ | ||
| 140 | void *to; /* current place in the buffer */ | ||
| 141 | void *stop; /* end of the buffer; overwritten if flush fails */ | ||
| 142 | int (*flush)(Fmt *); /* called when to == stop */ | ||
| 143 | void *farg; /* to make flush a closure */ | ||
| 144 | int nfmt; /* num chars formatted so far */ | ||
| 145 | va_list args; /* args passed to dofmt */ | ||
| 146 | int r; /* % format Rune */ | ||
| 147 | int width; | ||
| 148 | int prec; | ||
| 149 | ulong flags; | ||
| 150 | }; | ||
| 151 | |||
| 152 | enum{ | ||
| 153 | FmtWidth = 1, | ||
| 154 | FmtLeft = FmtWidth << 1, | ||
| 155 | FmtPrec = FmtLeft << 1, | ||
| 156 | FmtSharp = FmtPrec << 1, | ||
| 157 | FmtSpace = FmtSharp << 1, | ||
| 158 | FmtSign = FmtSpace << 1, | ||
| 159 | FmtZero = FmtSign << 1, | ||
| 160 | FmtUnsigned = FmtZero << 1, | ||
| 161 | FmtShort = FmtUnsigned << 1, | ||
| 162 | FmtLong = FmtShort << 1, | ||
| 163 | FmtVLong = FmtLong << 1, | ||
| 164 | FmtComma = FmtVLong << 1, | ||
| 165 | FmtByte = FmtComma << 1, | ||
| 166 | |||
| 167 | FmtFlag = FmtByte << 1 | ||
| 168 | }; | ||
| 169 | |||
| 170 | extern int print(char*, ...); | ||
| 171 | extern char* seprint(char*, char*, char*, ...); | ||
| 172 | extern char* vseprint(char*, char*, char*, va_list); | ||
| 173 | extern int snprint(char*, int, char*, ...); | ||
| 174 | extern int vsnprint(char*, int, char*, va_list); | ||
| 175 | extern char* smprint(char*, ...); | ||
| 176 | extern char* vsmprint(char*, va_list); | ||
| 177 | extern int sprint(char*, char*, ...); | ||
| 178 | extern int fprint(int, char*, ...); | ||
| 179 | extern int vfprint(int, char*, va_list); | ||
| 180 | |||
| 181 | extern int runesprint(Rune*, char*, ...); | ||
| 182 | extern int runesnprint(Rune*, int, char*, ...); | ||
| 183 | extern int runevsnprint(Rune*, int, char*, va_list); | ||
| 184 | extern Rune* runeseprint(Rune*, Rune*, char*, ...); | ||
| 185 | extern Rune* runevseprint(Rune*, Rune*, char*, va_list); | ||
| 186 | extern Rune* runesmprint(char*, ...); | ||
| 187 | extern Rune* runevsmprint(char*, va_list); | ||
| 188 | |||
| 189 | extern int fmtfdinit(Fmt*, int, char*, int); | ||
| 190 | extern int fmtfdflush(Fmt*); | ||
| 191 | extern int fmtstrinit(Fmt*); | ||
| 192 | extern char* fmtstrflush(Fmt*); | ||
| 193 | extern int runefmtstrinit(Fmt*); | ||
| 194 | extern Rune* runefmtstrflush(Fmt*); | ||
| 195 | |||
| 196 | extern int fmtinstall(int, int (*)(Fmt*)); | ||
| 197 | extern int dofmt(Fmt*, char*); | ||
| 198 | extern int dorfmt(Fmt*, Rune*); | ||
| 199 | extern int fmtprint(Fmt*, char*, ...); | ||
| 200 | extern int fmtvprint(Fmt*, char*, va_list); | ||
| 201 | extern int fmtrune(Fmt*, int); | ||
| 202 | extern int fmtstrcpy(Fmt*, char*); | ||
| 203 | extern int fmtrunestrcpy(Fmt*, Rune*); | ||
| 204 | /* | ||
| 205 | * error string for %r | ||
| 206 | * supplied on per os basis, not part of fmt library | ||
| 207 | */ | ||
| 208 | extern int errfmt(Fmt *f); | ||
| 209 | |||
| 210 | /* | ||
| 211 | * quoted strings | ||
| 212 | */ | ||
| 213 | extern char *unquotestrdup(char*); | ||
| 214 | extern Rune *unquoterunestrdup(Rune*); | ||
| 215 | extern char *quotestrdup(char*); | ||
| 216 | extern Rune *quoterunestrdup(Rune*); | ||
| 217 | extern int quotestrfmt(Fmt*); | ||
| 218 | extern int quoterunestrfmt(Fmt*); | ||
| 219 | extern void quotefmtinstall(void); | ||
| 220 | extern int (*doquote)(int); | ||
| 221 | |||
| 222 | /* | ||
| 223 | * random number | ||
| 224 | */ | ||
| 225 | extern int nrand(int); | ||
| 226 | |||
| 227 | /* | ||
| 228 | * random number | ||
| 229 | */ | ||
| 230 | extern ulong truerand(void); | ||
| 231 | extern ulong ntruerand(ulong); | ||
| 232 | |||
| 233 | /* | ||
| 234 | * math | ||
| 235 | */ | ||
| 236 | extern int isNaN(double); | ||
| 237 | extern int isInf(double, int); | ||
| 238 | extern double pow(double, double); | ||
| 239 | |||
| 240 | /* | ||
| 241 | * Time-of-day | ||
| 242 | */ | ||
| 243 | |||
| 244 | typedef struct Tm Tm; | ||
| 245 | struct Tm { | ||
| 246 | int sec; | ||
| 247 | int min; | ||
| 248 | int hour; | ||
| 249 | int mday; | ||
| 250 | int mon; | ||
| 251 | int year; | ||
| 252 | int wday; | ||
| 253 | int yday; | ||
| 254 | char zone[4]; | ||
| 255 | int tzoff; | ||
| 256 | }; | ||
| 257 | extern vlong osnsec(void); | ||
| 258 | #define nsec osnsec | ||
| 259 | |||
| 260 | /* | ||
| 261 | * one-of-a-kind | ||
| 262 | */ | ||
| 263 | extern void _assert(char*); | ||
| 264 | extern double charstod(int(*)(void*), void*); | ||
| 265 | extern char* cleanname(char*); | ||
| 266 | extern double frexp(double, int*); | ||
| 267 | extern uintptr getcallerpc(void*); | ||
| 268 | extern int getfields(char*, char**, int, int, char*); | ||
| 269 | extern char* getuser(void); | ||
| 270 | extern char* getwd(char*, int); | ||
| 271 | extern double ipow10(int); | ||
| 272 | extern double ldexp(double, int); | ||
| 273 | extern double modf(double, double*); | ||
| 274 | #define pow10 infpow10 | ||
| 275 | extern double pow10(int); | ||
| 276 | extern vlong strtoll(const char*, char**, int); | ||
| 277 | #define qsort infqsort | ||
| 278 | extern void qsort(void*, long, long, int (*)(void*, void*)); | ||
| 279 | extern uvlong strtoull(const char*, char**, int); | ||
| 280 | extern void sysfatal(char*, ...); | ||
| 281 | extern int dec64(uchar*, int, char*, int); | ||
| 282 | extern int enc64(char*, int, uchar*, int); | ||
| 283 | extern int dec32(uchar*, int, char*, int); | ||
| 284 | extern int enc32(char*, int, uchar*, int); | ||
| 285 | extern int dec16(uchar*, int, char*, int); | ||
| 286 | extern int enc16(char*, int, uchar*, int); | ||
| 287 | extern int encodefmt(Fmt*); | ||
| 288 | |||
| 289 | /* | ||
| 290 | * synchronization | ||
| 291 | */ | ||
| 292 | typedef | ||
| 293 | struct Lock { | ||
| 294 | int val; | ||
| 295 | int pid; | ||
| 296 | } Lock; | ||
| 297 | |||
| 298 | extern int _tas(int*); | ||
| 299 | |||
| 300 | extern void lock(Lock*); | ||
| 301 | extern void unlock(Lock*); | ||
| 302 | extern int canlock(Lock*); | ||
| 303 | |||
| 304 | typedef struct QLock QLock; | ||
| 305 | struct QLock | ||
| 306 | { | ||
| 307 | Lock use; /* to access Qlock structure */ | ||
| 308 | Proc *head; /* next process waiting for object */ | ||
| 309 | Proc *tail; /* last process waiting for object */ | ||
| 310 | int locked; /* flag */ | ||
| 311 | }; | ||
| 312 | |||
| 313 | extern void qlock(QLock*); | ||
| 314 | extern void qunlock(QLock*); | ||
| 315 | extern int canqlock(QLock*); | ||
| 316 | extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */ | ||
| 317 | |||
| 318 | typedef | ||
| 319 | struct RWLock | ||
| 320 | { | ||
| 321 | Lock l; /* Lock modify lock */ | ||
| 322 | QLock x; /* Mutual exclusion lock */ | ||
| 323 | QLock k; /* Lock for waiting writers */ | ||
| 324 | int readers; /* Count of readers in lock */ | ||
| 325 | } RWLock; | ||
| 326 | |||
| 327 | extern int canrlock(RWLock*); | ||
| 328 | extern int canwlock(RWLock*); | ||
| 329 | extern void rlock(RWLock*); | ||
| 330 | extern void runlock(RWLock*); | ||
| 331 | extern void wlock(RWLock*); | ||
| 332 | extern void wunlock(RWLock*); | ||
| 333 | |||
| 334 | /* | ||
| 335 | * network dialing | ||
| 336 | */ | ||
| 337 | #define NETPATHLEN 40 | ||
| 338 | |||
| 339 | /* | ||
| 340 | * system calls | ||
| 341 | * | ||
| 342 | */ | ||
| 343 | #define STATMAX 65535U /* max length of machine-independent stat structure */ | ||
| 344 | #define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */ | ||
| 345 | #define ERRMAX 128 /* max length of error string */ | ||
| 346 | |||
| 347 | #define MORDER 0x0003 /* mask for bits defining order of mounting */ | ||
| 348 | #define MREPL 0x0000 /* mount replaces object */ | ||
| 349 | #define MBEFORE 0x0001 /* mount goes before others in union directory */ | ||
| 350 | #define MAFTER 0x0002 /* mount goes after others in union directory */ | ||
| 351 | #define MCREATE 0x0004 /* permit creation in mounted directory */ | ||
| 352 | #define MCACHE 0x0010 /* cache some data */ | ||
| 353 | #define MMASK 0x0017 /* all bits on */ | ||
| 354 | |||
| 355 | #define OREAD 0 /* open for read */ | ||
| 356 | #define OWRITE 1 /* write */ | ||
| 357 | #define ORDWR 2 /* read and write */ | ||
| 358 | #define OEXEC 3 /* execute, == read but check execute permission */ | ||
| 359 | #define OTRUNC 16 /* or'ed in (except for exec), truncate file first */ | ||
| 360 | #define OCEXEC 32 /* or'ed in, close on exec */ | ||
| 361 | #define ORCLOSE 64 /* or'ed in, remove on close */ | ||
| 362 | #define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */ | ||
| 363 | |||
| 364 | #define AEXIST 0 /* accessible: exists */ | ||
| 365 | #define AEXEC 1 /* execute access */ | ||
| 366 | #define AWRITE 2 /* write access */ | ||
| 367 | #define AREAD 4 /* read access */ | ||
| 368 | |||
| 369 | /* bits in Qid.type */ | ||
| 370 | #define QTDIR 0x80 /* type bit for directories */ | ||
| 371 | #define QTAPPEND 0x40 /* type bit for append only files */ | ||
| 372 | #define QTEXCL 0x20 /* type bit for exclusive use files */ | ||
| 373 | #define QTMOUNT 0x10 /* type bit for mounted channel */ | ||
| 374 | #define QTAUTH 0x08 /* type bit for authentication file */ | ||
| 375 | #define QTFILE 0x00 /* plain file */ | ||
| 376 | |||
| 377 | /* bits in Dir.mode */ | ||
| 378 | #define DMDIR 0x80000000 /* mode bit for directories */ | ||
| 379 | #define DMAPPEND 0x40000000 /* mode bit for append only files */ | ||
| 380 | #define DMEXCL 0x20000000 /* mode bit for exclusive use files */ | ||
| 381 | #define DMMOUNT 0x10000000 /* mode bit for mounted channel */ | ||
| 382 | #define DMAUTH 0x08000000 /* mode bit for authentication file */ | ||
| 383 | #define DMREAD 0x4 /* mode bit for read permission */ | ||
| 384 | #define DMWRITE 0x2 /* mode bit for write permission */ | ||
| 385 | #define DMEXEC 0x1 /* mode bit for execute permission */ | ||
| 386 | |||
| 387 | typedef | ||
| 388 | struct Qid | ||
| 389 | { | ||
| 390 | uvlong path; | ||
| 391 | ulong vers; | ||
| 392 | uchar type; | ||
| 393 | } Qid; | ||
| 394 | |||
| 395 | typedef | ||
| 396 | struct Dir { | ||
| 397 | /* system-modified data */ | ||
| 398 | ushort type; /* server type */ | ||
| 399 | uint dev; /* server subtype */ | ||
| 400 | /* file data */ | ||
| 401 | Qid qid; /* unique id from server */ | ||
| 402 | ulong mode; /* permissions */ | ||
| 403 | ulong atime; /* last read time */ | ||
| 404 | ulong mtime; /* last write time */ | ||
| 405 | vlong length; /* file length */ | ||
| 406 | char *name; /* last element of path */ | ||
| 407 | char *uid; /* owner name */ | ||
| 408 | char *gid; /* group name */ | ||
| 409 | char *muid; /* last modifier name */ | ||
| 410 | } Dir; | ||
| 411 | |||
| 412 | extern Dir* dirstat(char*); | ||
| 413 | extern Dir* dirfstat(int); | ||
| 414 | extern int dirwstat(char*, Dir*); | ||
| 415 | extern int dirfwstat(int, Dir*); | ||
| 416 | extern long dirread(int, Dir**); | ||
| 417 | extern void nulldir(Dir*); | ||
| 418 | extern long dirreadall(int, Dir**); | ||
| 419 | |||
| 420 | typedef | ||
| 421 | struct Waitmsg | ||
| 422 | { | ||
| 423 | int pid; /* of loved one */ | ||
| 424 | ulong time[3]; /* of loved one & descendants */ | ||
| 425 | char *msg; | ||
| 426 | } Waitmsg; | ||
| 427 | |||
| 428 | extern void _exits(char*); | ||
| 429 | |||
| 430 | extern void exits(char*); | ||
| 431 | extern int create(char*, int, int); | ||
| 432 | extern int errstr(char*, uint); | ||
| 433 | |||
| 434 | extern void perror(const char*); | ||
| 435 | extern long readn(int, void*, long); | ||
| 436 | extern int remove(const char*); | ||
| 437 | extern void rerrstr(char*, uint); | ||
| 438 | extern vlong seek(int, vlong, int); | ||
| 439 | extern int segflush(void*, ulong); | ||
| 440 | extern void werrstr(char*, ...); | ||
| 441 | |||
| 442 | extern char *argv0; | ||
| 443 | #define ARGBEGIN for((argv0||(argv0=*argv)),argv++,argc--;\ | ||
| 444 | argv[0] && argv[0][0]=='-' && argv[0][1];\ | ||
| 445 | argc--, argv++) {\ | ||
| 446 | char *_args, *_argt;\ | ||
| 447 | Rune _argc;\ | ||
| 448 | _args = &argv[0][1];\ | ||
| 449 | if(_args[0]=='-' && _args[1]==0){\ | ||
| 450 | argc--; argv++; break;\ | ||
| 451 | }\ | ||
| 452 | _argc = 0;\ | ||
| 453 | while(*_args && (_args += chartorune(&_argc, _args)))\ | ||
| 454 | switch(_argc) | ||
| 455 | #define ARGEND SET(_argt);USED(_argt);USED(_argc); USED(_args);}USED(argv); USED(argc); | ||
| 456 | #define ARGF() (_argt=_args, _args="",\ | ||
| 457 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) | ||
| 458 | #define EARGF(x) (_argt=_args, _args="",\ | ||
| 459 | (*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0))) | ||
| 460 | |||
| 461 | #define ARGC() _argc | ||
| 462 | |||
| 463 | /* | ||
| 464 | * Extensions for Inferno to basic libc.h | ||
| 465 | */ | ||
| 466 | |||
| 467 | #define setbinmode() | ||
| 468 | |||
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,2 @@ | |||
| 1 | Acid pid | ||
| 2 | Acid -l alef -l symsfile pid | ||
| @@ -0,0 +1,12 @@ | |||
| 1 | Capital A Acid is a rudimentary acme interface to the debugger acid. | ||
| 2 | It uses a win to provide an interactive window for acid. In that window, | ||
| 3 | a couple of extra acme-specific features are enabled: | ||
| 4 | |||
| 5 | w(command) | ||
| 6 | runs the command and places its output in a new window. | ||
| 7 | e.g. w(lstk()) places the stack trace in a distinct window. | ||
| 8 | |||
| 9 | Also, in any such window, text executed with button 2 is | ||
| 10 | presented as input to acid in the main Acid window. Thus, for | ||
| 11 | example, one may evaluate variables presented in a stack trace | ||
| 12 | by `executing' it with button 2. | ||
| @@ -0,0 +1,5 @@ | |||
| 1 | win | ||
| 2 | new command ... | ||
| 3 | aspell file | ||
| 4 | adiff file1 file2 | ||
| 5 | adict -d oed | ||
| @@ -0,0 +1,25 @@ | |||
| 1 | This directory and its subdirectory $cputype are always mounted at | ||
| 2 | the end of /bin for programs run from acme. They hold a collection | ||
| 3 | of small acme-specific applications: | ||
| 4 | |||
| 5 | win [command] | ||
| 6 | Create an acme window to serve as a terminal, analogous | ||
| 7 | to xterm. By default, it runs the shell, rc, but it works with | ||
| 8 | any interactive program, e.g. hoc. Within the window, | ||
| 9 | commands executed with button 2 are 'executed' by sending | ||
| 10 | their text to the standard input of the command, appending | ||
| 11 | a newline if necessary. | ||
| 12 | new command | ||
| 13 | Run the non-interactive command, placing its standard and | ||
| 14 | diagnostic output in a new window. | ||
| 15 | aspell file | ||
| 16 | Run spell on the file, labeling the output with addresses so | ||
| 17 | misspelled words can be found in context using button 3. | ||
| 18 | adiff file1 file2 | ||
| 19 | Run diff on the files, labeling the output with addresses so | ||
| 20 | changes can be found in context using button 3. | ||
| 21 | adict | ||
| 22 | Interactive version of dict(1). Button 3 looks up words and | ||
| 23 | may be applied to any word in any adict window. | ||
| 24 | When a word has multiple definitions, indicate the number | ||
| 25 | (as in acme Mail) to disambiguate. | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,4 @@ | |||
| 1 | e file | x '/regexp/' | c 'replacement' | ||
| 2 | e 'file:0,$' | x '/.*word.*\n/' | p -n | ||
| 3 | e file | pipe command args ... | ||
| 4 | New /absolute/file/name | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,31 @@ | |||
| 1 | The programs collected in /acme/edit offer a sam-like command interface | ||
| 2 | to acme windows. The guide file | ||
| 3 | /acme/edit/guide | ||
| 4 | holds templates for several editing operations implemented | ||
| 5 | by external programs. These programs, composed in | ||
| 6 | a pipeline, refine the sections of a file to be modified. | ||
| 7 | Thus in sam when one says | ||
| 8 | x/.*\n/ g/foo/ p | ||
| 9 | in /acme/edit one runs | ||
| 10 | x '/.*\n/' | g '/foo/' | p | ||
| 11 | The e command, unrelated to e in sam, disambiguates file names, collects | ||
| 12 | lists of names, etc., and produces input suitable for the other tools. | ||
| 13 | For example: | ||
| 14 | e '/usr/rob/acme:0,$' | x /oldname/ | c /newname/ | ||
| 15 | changes oldname to newname in all the files loaded in acme whose names match | ||
| 16 | the literal text /usr/rob/acme. | ||
| 17 | |||
| 18 | The commands in /acme/edit are | ||
| 19 | e | ||
| 20 | x | ||
| 21 | g | ||
| 22 | c | ||
| 23 | d | ||
| 24 | p | ||
| 25 | pipe (like sam's | , which can't be used for syntactic reasons) | ||
| 26 | |||
| 27 | p takes a -n flag analogous to grep's -n. There is no s command. | ||
| 28 | e has a -l flag to produce line numbers instead of the default character numbers. | ||
| 29 | Its implementation is poor but sufficient for the mundane job of recreating | ||
| 30 | the occasional line number for tools like acid; its use with the other commands | ||
| 31 | in this directory is discouraged. | ||
Binary file not shown.
Binary file not shown.
Binary file not shown.
| @@ -0,0 +1,5 @@ | |||
| 1 | Mail /mail/box/$user/stored | ||
| 2 | |||
| 3 | Mailpop3 | ||
| 4 | mkbox /mail/box/$user/new_box | ||
| 5 | mail -'x' someaddress | ||
Binary file not shown.
| @@ -0,0 +1,29 @@ | |||
| 1 | Mail is the single program in this directory. Its argument specifies | ||
| 2 | the mail box to read, default /mail/box/$user/mbox. | ||
| 3 | For example, running | ||
| 4 | Mail /mail/box/$user/stored | ||
| 5 | (a line in the guide file) looks at saved mail. | ||
| 6 | |||
| 7 | Mail maintains a window containing headers for all the | ||
| 8 | messages in the mailbox and monitors the mailbox for new messages. | ||
| 9 | Using button 3 to indicate a message number opens | ||
| 10 | a window on that message. commands in the mailbox window are | ||
| 11 | Put Write the mailbox back to the file (never done automatically) | ||
| 12 | Mail Make a new message window ready to mail someone. | ||
| 13 | Takes argument names analogously to acme's New. | ||
| 14 | Del Exit Mail, after checking that mailbox isn't modified. | ||
| 15 | New messages appear at the top of the window and are highlighted upon arrival. | ||
| 16 | (The messages are numbered oldest to newest, the opposite of regular mail.) | ||
| 17 | |||
| 18 | Message windows have a simple format: the first line, up to the first tab or newline, | ||
| 19 | holds the sender or, when sending, the addressee. Edit the line to change who the | ||
| 20 | message goes to. Message windows contain the commands | ||
| 21 | Reply Make a new window to compose a reply to this message | ||
| 22 | Delmesg Delete the message from the screen and from the mailbox | ||
| 23 | Del Delete the window, leaving the message in the mailbox | ||
| 24 | Post Send the message to the addressee | ||
| 25 | Save Save to the named mailbox, default/mail/box/$user/stored | ||
| 26 | Save takes a full file name; if that name has no slashes, the file is taken | ||
| 27 | to be in /mail/box/$user and must already exist. Use mkbox in the guide to | ||
| 28 | create target mailboxes in /mail/box/$user. | ||
| 29 | Reply and mail windows contain an obvious subset of the commands. | ||
| @@ -0,0 +1,25 @@ | |||
| 1 | This copyright NOTICE applies to all files in this directory and | ||
| 2 | subdirectories, unless another copyright notice appears in a given | ||
| 3 | file or subdirectory. If you take substantial code from this software to use in | ||
| 4 | other programs, you must somehow include with it an appropriate | ||
| 5 | copyright notice that includes the copyright notice and the other | ||
| 6 | notices below. It is fine (and often tidier) to do that in a separate | ||
| 7 | file such as NOTICE, LICENCE or COPYING. | ||
| 8 | |||
| 9 | Copyright © 1995-1999 Lucent Technologies Inc. | ||
| 10 | Portions Copyright © 1997-2000 Vita Nuova Limited | ||
| 11 | Portions Copyright © 2000-2010 Vita Nuova Holdings Limited | ||
| 12 | |||
| 13 | This program is free software; you can redistribute it and/or modify | ||
| 14 | it under the terms of the GNU General Public License as published by | ||
| 15 | the Free Software Foundation; either version 2 of the License, or | ||
| 16 | (at your option) any later version. | ||
| 17 | |||
| 18 | This program is distributed in the hope that it will be useful, | ||
| 19 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | GNU General Public License for more details. | ||
| 22 | |||
| 23 | You should have received a copy of the GNU General Public License | ||
| 24 | along with this program; if not, write to the Free Software | ||
| 25 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| @@ -0,0 +1,1112 @@ | |||
| 1 | implement Acme; | ||
| 2 | |||
| 3 | include "common.m"; | ||
| 4 | |||
| 5 | sys : Sys; | ||
| 6 | bufio : Bufio; | ||
| 7 | workdir : Workdir; | ||
| 8 | drawm : Draw; | ||
| 9 | styx : Styx; | ||
| 10 | acme : Acme; | ||
| 11 | gui : Gui; | ||
| 12 | graph : Graph; | ||
| 13 | dat : Dat; | ||
| 14 | framem : Framem; | ||
| 15 | utils : Utils; | ||
| 16 | regx : Regx; | ||
| 17 | scrl : Scroll; | ||
| 18 | textm : Textm; | ||
| 19 | filem : Filem; | ||
| 20 | windowm : Windowm; | ||
| 21 | rowm : Rowm; | ||
| 22 | columnm : Columnm; | ||
| 23 | bufferm : Bufferm; | ||
| 24 | diskm : Diskm; | ||
| 25 | exec : Exec; | ||
| 26 | look : Look; | ||
| 27 | timerm : Timerm; | ||
| 28 | fsys : Fsys; | ||
| 29 | xfidm : Xfidm; | ||
| 30 | plumbmsg : Plumbmsg; | ||
| 31 | editm: Edit; | ||
| 32 | editlog: Editlog; | ||
| 33 | editcmd: Editcmd; | ||
| 34 | styxaux: Styxaux; | ||
| 35 | |||
| 36 | sprint : import sys; | ||
| 37 | BACK, HIGH, BORD, TEXT, HTEXT, NCOL : import Framem; | ||
| 38 | Point, Rect, Font, Image, Display, Pointer: import drawm; | ||
| 39 | TRUE, FALSE, maxtab : import dat; | ||
| 40 | Ref, Reffont, Command, Timer, Lock, Cursor : import dat; | ||
| 41 | row, reffont, activecol, mouse, typetext, mousetext, barttext, argtext, seltext, button, modbutton, colbutton, arrowcursor, boxcursor, plumbed : import dat; | ||
| 42 | Xfid : import xfidm; | ||
| 43 | cmouse, ckeyboard, cwait, ccommand, ckill, cxfidalloc, cxfidfree, cerr, cplumb, cedit : import dat; | ||
| 44 | font, bflush, balloc, draw : import graph; | ||
| 45 | Arg, PNPROC, PNGROUP : import utils; | ||
| 46 | arginit, argopt, argf, error, warning, postnote : import utils; | ||
| 47 | yellow, green, red, blue, black, white, mainwin, display : import gui; | ||
| 48 | Disk : import diskm; | ||
| 49 | Row : import rowm; | ||
| 50 | Column : import columnm; | ||
| 51 | Window : import windowm; | ||
| 52 | Text, Tag, Body, Columntag : import textm; | ||
| 53 | Buffer : import bufferm; | ||
| 54 | snarfbuf : import exec; | ||
| 55 | Msg : import plumbmsg; | ||
| 56 | |||
| 57 | tfd : ref Sys->FD; | ||
| 58 | lasttime : int; | ||
| 59 | |||
| 60 | init(ctxt : ref Draw->Context, argl : list of string) | ||
| 61 | { | ||
| 62 | acmectxt = ctxt; | ||
| 63 | |||
| 64 | sys = load Sys Sys->PATH; | ||
| 65 | sys->pctl(Sys->NEWPGRP, nil); | ||
| 66 | |||
| 67 | { | ||
| 68 | # tfd = sys->create("./time", Sys->OWRITE, 8r600); | ||
| 69 | # lasttime = sys->millisec(); | ||
| 70 | bufio = load Bufio Bufio->PATH; | ||
| 71 | workdir = load Workdir Workdir->PATH; | ||
| 72 | drawm = load Draw Draw->PATH; | ||
| 73 | |||
| 74 | styx = load Styx Styx->PATH; | ||
| 75 | |||
| 76 | acme = load Acme SELF; | ||
| 77 | |||
| 78 | gui = load Gui path(Gui->PATH); | ||
| 79 | graph = load Graph path(Graph->PATH); | ||
| 80 | dat = load Dat path(Dat->PATH); | ||
| 81 | framem = load Framem path(Framem->PATH); | ||
| 82 | utils = load Utils path(Utils->PATH); | ||
| 83 | regx = load Regx path(Regx->PATH); | ||
| 84 | scrl = load Scroll path(Scroll->PATH); | ||
| 85 | textm = load Textm path(Textm->PATH); | ||
| 86 | filem = load Filem path(Filem->PATH); | ||
| 87 | windowm = load Windowm path(Windowm->PATH); | ||
| 88 | rowm = load Rowm path(Rowm->PATH); | ||
| 89 | columnm = load Columnm path(Columnm->PATH); | ||
| 90 | bufferm = load Bufferm path(Bufferm->PATH); | ||
| 91 | diskm = load Diskm path(Diskm->PATH); | ||
| 92 | exec = load Exec path(Exec->PATH); | ||
| 93 | look = load Look path(Look->PATH); | ||
| 94 | timerm = load Timerm path(Timerm->PATH); | ||
| 95 | fsys = load Fsys path(Fsys->PATH); | ||
| 96 | xfidm = load Xfidm path(Xfidm->PATH); | ||
| 97 | plumbmsg = load Plumbmsg Plumbmsg->PATH; | ||
| 98 | editm = load Edit path(Edit->PATH); | ||
| 99 | editlog = load Editlog path(Editlog->PATH); | ||
| 100 | editcmd = load Editcmd path(Editcmd->PATH); | ||
| 101 | styxaux = load Styxaux path(Styxaux->PATH); | ||
| 102 | |||
| 103 | mods := ref Dat->Mods(sys, bufio, drawm, styx, styxaux, | ||
| 104 | acme, gui, graph, dat, framem, | ||
| 105 | utils, regx, scrl, | ||
| 106 | textm, filem, windowm, rowm, columnm, | ||
| 107 | bufferm, diskm, exec, look, timerm, | ||
| 108 | fsys, xfidm, plumbmsg, editm, editlog, editcmd); | ||
| 109 | |||
| 110 | styx->init(); | ||
| 111 | styxaux->init(); | ||
| 112 | |||
| 113 | utils->init(mods); | ||
| 114 | gui->init(mods); | ||
| 115 | graph->init(mods); | ||
| 116 | dat->init(mods); | ||
| 117 | framem->init(mods); | ||
| 118 | regx->init(mods); | ||
| 119 | scrl->init(mods); | ||
| 120 | textm->init(mods); | ||
| 121 | filem->init(mods); | ||
| 122 | windowm->init(mods); | ||
| 123 | rowm->init(mods); | ||
| 124 | columnm->init(mods); | ||
| 125 | bufferm->init(mods); | ||
| 126 | diskm->init(mods); | ||
| 127 | exec->init(mods); | ||
| 128 | look->init(mods); | ||
| 129 | timerm->init(mods); | ||
| 130 | fsys->init(mods); | ||
| 131 | xfidm->init(mods); | ||
| 132 | editm->init(mods); | ||
| 133 | editlog->init(mods); | ||
| 134 | editcmd->init(mods); | ||
| 135 | |||
| 136 | utils->debuginit(); | ||
| 137 | |||
| 138 | if (plumbmsg->init(1, "edit", Dat->PLUMBSIZE) >= 0) | ||
| 139 | plumbed = 1; | ||
| 140 | |||
| 141 | main(argl); | ||
| 142 | |||
| 143 | } | ||
| 144 | # exception{ | ||
| 145 | # * => | ||
| 146 | # sys->fprint(sys->fildes(2), "acme: fatal: %s\n", utils->getexc()); | ||
| 147 | # sys->print("acme: fatal: %s\n", utils->getexc()); | ||
| 148 | # shutdown("error"); | ||
| 149 | # } | ||
| 150 | } | ||
| 151 | |||
| 152 | timing(s : string) | ||
| 153 | { | ||
| 154 | thistime := sys->millisec(); | ||
| 155 | sys->fprint(tfd, "%s %d\n", s, thistime-lasttime); | ||
| 156 | lasttime = thistime; | ||
| 157 | } | ||
| 158 | |||
| 159 | path(p : string) : string | ||
| 160 | { | ||
| 161 | if (RELEASECOPY) | ||
| 162 | return p; | ||
| 163 | else { | ||
| 164 | # inlined strrchr since not loaded yet | ||
| 165 | for (n := len p - 1; n >= 0; n--) | ||
| 166 | if (p[n] == '/') | ||
| 167 | break; | ||
| 168 | if (n >= 0) | ||
| 169 | p = p[n+1:]; | ||
| 170 | return "/usr/jrf/acme/" + p; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | waitpid0, waitpid1 : int; | ||
| 175 | mainpid : int; | ||
| 176 | |||
| 177 | fontcache : array of ref Reffont; | ||
| 178 | nfontcache : int; | ||
| 179 | reffonts : array of ref Reffont; | ||
| 180 | deffontnames := array[2] of { | ||
| 181 | "/fonts/lucidasans/euro.8.font", | ||
| 182 | "/fonts/lucm/unicode.9.font", | ||
| 183 | }; | ||
| 184 | |||
| 185 | command : ref Command; | ||
| 186 | |||
| 187 | WPERCOL : con 8; | ||
| 188 | |||
| 189 | NSnarf : con 32; | ||
| 190 | snarfrune : ref Dat->Astring; | ||
| 191 | |||
| 192 | main(argl : list of string) | ||
| 193 | { | ||
| 194 | i, ac : int; | ||
| 195 | loadfile : string; | ||
| 196 | p : int; | ||
| 197 | c : ref Column; | ||
| 198 | arg : ref Arg; | ||
| 199 | ncol : int; | ||
| 200 | |||
| 201 | ncol = -1; | ||
| 202 | |||
| 203 | mainpid = sys->pctl(0, nil); | ||
| 204 | loadfile = nil; | ||
| 205 | fontnames = array[2] of string; | ||
| 206 | fontnames[0:] = deffontnames[0:2]; | ||
| 207 | f := utils->getenv("acme-font"); | ||
| 208 | if (f != nil) | ||
| 209 | fontnames[0] = f; | ||
| 210 | f = utils->getenv("acme-Font"); | ||
| 211 | if (f != nil) | ||
| 212 | fontnames[1] = f; | ||
| 213 | arg = arginit(argl); | ||
| 214 | while(ac = argopt(arg)) case(ac){ | ||
| 215 | 'b' => | ||
| 216 | dat->bartflag = TRUE; | ||
| 217 | 'c' => | ||
| 218 | ncol = int argf(arg); | ||
| 219 | 'f' => | ||
| 220 | fontnames[0] = argf(arg); | ||
| 221 | 'F' => | ||
| 222 | fontnames[1] = argf(arg); | ||
| 223 | 'l' => | ||
| 224 | loadfile = argf(arg); | ||
| 225 | } | ||
| 226 | |||
| 227 | dat->home = utils->getenv("home"); | ||
| 228 | if (dat->home == nil) | ||
| 229 | dat->home = utils->gethome(utils->getuser()); | ||
| 230 | ts := utils->getenv("tabstop"); | ||
| 231 | if (ts != nil) | ||
| 232 | maxtab = int ts; | ||
| 233 | if (maxtab <= 0) | ||
| 234 | maxtab = 4; | ||
| 235 | snarfrune = utils->stralloc(NSnarf); | ||
| 236 | sys->pctl(Sys->FORKNS|Sys->FORKENV, nil); | ||
| 237 | utils->setenv("font", fontnames[0]); | ||
| 238 | sys->bind("/acme/dis", "/dis", Sys->MBEFORE); | ||
| 239 | wdir = workdir->init(); | ||
| 240 | if (wdir == nil) | ||
| 241 | wdir = "."; | ||
| 242 | workdir = nil; | ||
| 243 | |||
| 244 | graph->binit(); | ||
| 245 | font = Font.open(display, fontnames[0]); | ||
| 246 | if(font == nil){ | ||
| 247 | fontnames[0] = deffontnames[0]; | ||
| 248 | font = Font.open(display, fontnames[0]); | ||
| 249 | if (font == nil) { | ||
| 250 | warning(nil, sprint("can't open font file %s: %r\n", fontnames[0])); | ||
| 251 | return; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | reffont = ref Reffont; | ||
| 255 | reffont.r = Ref.init(); | ||
| 256 | reffont.f = font; | ||
| 257 | reffonts = array[2] of ref Reffont; | ||
| 258 | reffonts[0] = reffont; | ||
| 259 | reffont.r.inc(); # one to hold up 'font' variable | ||
| 260 | reffont.r.inc(); # one to hold up reffonts[0] | ||
| 261 | fontcache = array[1] of ref Reffont; | ||
| 262 | nfontcache = 1; | ||
| 263 | fontcache[0] = reffont; | ||
| 264 | |||
| 265 | iconinit(); | ||
| 266 | usercolinit(); | ||
| 267 | timerm->timerinit(); | ||
| 268 | regx->rxinit(); | ||
| 269 | |||
| 270 | cwait = chan of string; | ||
| 271 | ccommand = chan of ref Command; | ||
| 272 | ckill = chan of string; | ||
| 273 | cxfidalloc = chan of ref Xfid; | ||
| 274 | cxfidfree = chan of ref Xfid; | ||
| 275 | cerr = chan of string; | ||
| 276 | cplumb = chan of ref Msg; | ||
| 277 | cedit = chan of int; | ||
| 278 | |||
| 279 | gui->spawnprocs(); | ||
| 280 | # spawn keyboardproc(); | ||
| 281 | # spawn mouseproc(); | ||
| 282 | sync := chan of int; | ||
| 283 | spawn waitproc(sys->pctl(0, nil), sync); | ||
| 284 | <- sync; | ||
| 285 | spawn plumbproc(); | ||
| 286 | |||
| 287 | fsys->fsysinit(); | ||
| 288 | dat->disk = (dat->disk).init(); | ||
| 289 | row = rowm->newrow(); | ||
| 290 | if(loadfile != nil) { | ||
| 291 | row.qlock.lock(); # tasks->procs now | ||
| 292 | row.loadx(loadfile, TRUE); | ||
| 293 | row.qlock.unlock(); | ||
| 294 | } | ||
| 295 | else{ | ||
| 296 | row.init(mainwin.clipr); | ||
| 297 | if(ncol < 0){ | ||
| 298 | if(arg.av == nil) | ||
| 299 | ncol = 2; | ||
| 300 | else{ | ||
| 301 | ncol = (len arg.av+(WPERCOL-1))/WPERCOL; | ||
| 302 | if(ncol < 2) | ||
| 303 | ncol = 2; | ||
| 304 | } | ||
| 305 | } | ||
| 306 | if(ncol == 0) | ||
| 307 | ncol = 2; | ||
| 308 | for(i=0; i<ncol; i++){ | ||
| 309 | c = row.add(nil, -1); | ||
| 310 | if(c==nil && i==0) | ||
| 311 | error("initializing columns"); | ||
| 312 | } | ||
| 313 | c = row.col[row.ncol-1]; | ||
| 314 | if(arg.av == nil) | ||
| 315 | readfile(c, wdir); | ||
| 316 | else | ||
| 317 | i = 0; | ||
| 318 | for( ; arg.av != nil; arg.av = tl arg.av){ | ||
| 319 | filen := hd arg.av; | ||
| 320 | p = utils->strrchr(filen, '/'); | ||
| 321 | if((p>=0 && filen[p:] == "/guide") || i/WPERCOL>=row.ncol) | ||
| 322 | readfile(c, filen); | ||
| 323 | else | ||
| 324 | readfile(row.col[i/WPERCOL], filen); | ||
| 325 | i++; | ||
| 326 | } | ||
| 327 | } | ||
| 328 | bflush(); | ||
| 329 | |||
| 330 | spawn keyboardtask(); | ||
| 331 | spawn mousetask(); | ||
| 332 | spawn waittask(); | ||
| 333 | spawn xfidalloctask(); | ||
| 334 | |||
| 335 | # notify(shutdown); | ||
| 336 | # waitc := chan of int; | ||
| 337 | # <-waitc; | ||
| 338 | # killprocs(); | ||
| 339 | exit; | ||
| 340 | } | ||
| 341 | |||
| 342 | readfile(c : ref Column, s : string) | ||
| 343 | { | ||
| 344 | w : ref Window; | ||
| 345 | r : string; | ||
| 346 | nr : int; | ||
| 347 | |||
| 348 | w = c.add(nil, nil, -1); | ||
| 349 | (r, nr) = look->cleanname(s, len s); | ||
| 350 | w.setname(r, nr); | ||
| 351 | w.body.loadx(0, s, 1); | ||
| 352 | w.body.file.mod = FALSE; | ||
| 353 | w.dirty = FALSE; | ||
| 354 | w.settag(); | ||
| 355 | scrl->scrdraw(w.body); | ||
| 356 | w.tag.setselect(w.tag.file.buf.nc, w.tag.file.buf.nc); | ||
| 357 | } | ||
| 358 | |||
| 359 | oknotes := array[6] of { | ||
| 360 | "delete", | ||
| 361 | "hangup", | ||
| 362 | "kill", | ||
| 363 | "exit", | ||
| 364 | "error", | ||
| 365 | nil | ||
| 366 | }; | ||
| 367 | |||
| 368 | dumping : int; | ||
| 369 | |||
| 370 | shutdown(msg : string) | ||
| 371 | { | ||
| 372 | i : int; | ||
| 373 | |||
| 374 | # notify(nil); | ||
| 375 | if(!dumping && msg != "kill" && msg != "exit" && (1 || sys->pctl(0, nil)==mainpid) && row != nil){ | ||
| 376 | dumping = TRUE; | ||
| 377 | row.dump(nil); | ||
| 378 | } | ||
| 379 | for(i=0; oknotes[i] != nil; i++) | ||
| 380 | if(utils->strncmp(oknotes[i], msg, len oknotes[i]) == 0) { | ||
| 381 | killprocs(); | ||
| 382 | exit; | ||
| 383 | } | ||
| 384 | # killprocs(); | ||
| 385 | sys->fprint(sys->fildes(2), "acme: %s\n", msg); | ||
| 386 | sys->print("acme: %s\n", msg); | ||
| 387 | # exit; | ||
| 388 | } | ||
| 389 | |||
| 390 | acmeexit(err: string) | ||
| 391 | { | ||
| 392 | if(err != nil) | ||
| 393 | shutdown(err); | ||
| 394 | graph->cursorswitch(nil); | ||
| 395 | if (plumbed) | ||
| 396 | plumbmsg->shutdown(); | ||
| 397 | killprocs(); | ||
| 398 | gui->killwins(); | ||
| 399 | exit; | ||
| 400 | } | ||
| 401 | |||
| 402 | killprocs() | ||
| 403 | { | ||
| 404 | c : ref Command; | ||
| 405 | kill := "kill"; | ||
| 406 | thispid := sys->pctl(0, nil); | ||
| 407 | fsys->fsysclose(); | ||
| 408 | |||
| 409 | postnote(PNPROC, thispid, mousepid, kill); | ||
| 410 | postnote(PNPROC, thispid, keyboardpid, kill); | ||
| 411 | postnote(PNPROC, thispid, timerpid, kill); | ||
| 412 | postnote(PNPROC, thispid, waitpid0, kill); | ||
| 413 | postnote(PNPROC, thispid, waitpid1, kill); | ||
| 414 | postnote(PNPROC, thispid, fsyspid, kill); | ||
| 415 | postnote(PNPROC, thispid, mainpid, kill); | ||
| 416 | postnote(PNPROC, thispid, keytid, kill); | ||
| 417 | postnote(PNPROC, thispid, mousetid, kill); | ||
| 418 | postnote(PNPROC, thispid, waittid, kill); | ||
| 419 | postnote(PNPROC, thispid, xfidalloctid, kill); | ||
| 420 | # postnote(PNPROC, thispid, lockpid, kill); | ||
| 421 | postnote(PNPROC, thispid, plumbpid, kill); | ||
| 422 | |||
| 423 | # draw(mainwin, mainwin.r, white, nil, mainwin.r.min); | ||
| 424 | |||
| 425 | for(c=command; c != nil; c=c.next) | ||
| 426 | postnote(PNGROUP, thispid, c.pid, "kill"); | ||
| 427 | |||
| 428 | xfidm->xfidkill(); | ||
| 429 | } | ||
| 430 | |||
| 431 | keytid : int; | ||
| 432 | mousetid : int; | ||
| 433 | waittid : int; | ||
| 434 | xfidalloctid : int; | ||
| 435 | |||
| 436 | keyboardtask() | ||
| 437 | { | ||
| 438 | r : int; | ||
| 439 | timer : ref Timer; | ||
| 440 | null : ref Timer; | ||
| 441 | t : ref Text; | ||
| 442 | |||
| 443 | { | ||
| 444 | keytid = sys->pctl(0, nil); | ||
| 445 | null = ref Timer; | ||
| 446 | null.c = chan of int; | ||
| 447 | timer = null; | ||
| 448 | typetext = nil; | ||
| 449 | for(;;){ | ||
| 450 | alt{ | ||
| 451 | <-(timer.c) => | ||
| 452 | timerm->timerstop(timer); | ||
| 453 | t = typetext; | ||
| 454 | if(t!=nil && t.what==Tag && !t.w.qlock.locked()){ | ||
| 455 | t.w.lock('K'); | ||
| 456 | t.w.commit(t); | ||
| 457 | t.w.unlock(); | ||
| 458 | bflush(); | ||
| 459 | } | ||
| 460 | timer = null; | ||
| 461 | r = <-ckeyboard => | ||
| 462 | gotkey := 1; | ||
| 463 | while (gotkey) { | ||
| 464 | typetext = row.typex(r, mouse.xy); | ||
| 465 | t = typetext; | ||
| 466 | if(t!=nil && t.col!=nil) | ||
| 467 | activecol = t.col; | ||
| 468 | if(t!=nil && t.w!=nil) | ||
| 469 | t.w.body.file.curtext = t.w.body; | ||
| 470 | if(timer != null) | ||
| 471 | spawn timerm->timerwaittask(timer); | ||
| 472 | if(t!=nil && t.what==Tag) | ||
| 473 | timer = timerm->timerstart(500); | ||
| 474 | else | ||
| 475 | timer = null; | ||
| 476 | alt { | ||
| 477 | r = <- ckeyboard => | ||
| 478 | gotkey = 1; # do this case again | ||
| 479 | * => | ||
| 480 | gotkey = 0; | ||
| 481 | } | ||
| 482 | bflush(); | ||
| 483 | } | ||
| 484 | } | ||
| 485 | } | ||
| 486 | } | ||
| 487 | exception{ | ||
| 488 | * => | ||
| 489 | shutdown(utils->getexc()); | ||
| 490 | raise; | ||
| 491 | # acmeexit(nil); | ||
| 492 | } | ||
| 493 | } | ||
| 494 | |||
| 495 | mousetask() | ||
| 496 | { | ||
| 497 | t, argt : ref Text; | ||
| 498 | but, ok : int; | ||
| 499 | q0, q1 : int; | ||
| 500 | w : ref Window; | ||
| 501 | m : ref Msg; | ||
| 502 | |||
| 503 | { | ||
| 504 | mousetid = sys->pctl(0, nil); | ||
| 505 | sync := chan of int; | ||
| 506 | spawn waitproc(mousetid, sync); | ||
| 507 | <- sync; | ||
| 508 | for(;;){ | ||
| 509 | alt{ | ||
| 510 | *mouse = *<-cmouse => | ||
| 511 | row.qlock.lock(); | ||
| 512 | if (mouse.buttons & M_QUIT) { | ||
| 513 | if (row.clean(TRUE)) | ||
| 514 | acmeexit(nil); | ||
| 515 | # shutdown("kill"); | ||
| 516 | row.qlock.unlock(); | ||
| 517 | break; | ||
| 518 | } | ||
| 519 | if (mouse.buttons & M_HELP) { | ||
| 520 | warning(nil, "no help provided (yet)"); | ||
| 521 | bflush(); | ||
| 522 | row.qlock.unlock(); | ||
| 523 | break; | ||
| 524 | } | ||
| 525 | if(mouse.buttons & M_RESIZE){ | ||
| 526 | draw(mainwin, mainwin.r, white, nil, mainwin.r.min); | ||
| 527 | scrl->scrresize(); | ||
| 528 | row.reshape(mainwin.clipr); | ||
| 529 | bflush(); | ||
| 530 | row.qlock.unlock(); | ||
| 531 | break; | ||
| 532 | } | ||
| 533 | t = row.which(mouse.xy); | ||
| 534 | if(t!=mousetext && mousetext!=nil && mousetext.w!=nil){ | ||
| 535 | mousetext.w.lock('M'); | ||
| 536 | mousetext.eq0 = ~0; | ||
| 537 | mousetext.w.commit(mousetext); | ||
| 538 | mousetext.w.unlock(); | ||
| 539 | } | ||
| 540 | mousetext = t; | ||
| 541 | if(t == nil) { | ||
| 542 | bflush(); | ||
| 543 | row.qlock.unlock(); | ||
| 544 | break; | ||
| 545 | } | ||
| 546 | w = t.w; | ||
| 547 | if(t==nil || mouse.buttons==0) { | ||
| 548 | bflush(); | ||
| 549 | row.qlock.unlock(); | ||
| 550 | break; | ||
| 551 | } | ||
| 552 | if(w != nil) | ||
| 553 | w.body.file.curtext = w.body; | ||
| 554 | but = 0; | ||
| 555 | if(mouse.buttons == 1) | ||
| 556 | but = 1; | ||
| 557 | else if(mouse.buttons == 2) | ||
| 558 | but = 2; | ||
| 559 | else if(mouse.buttons == 4) | ||
| 560 | but = 3; | ||
| 561 | barttext = t; | ||
| 562 | if(t.what==Body && mouse.xy.in(t.scrollr)){ | ||
| 563 | if(but){ | ||
| 564 | w.lock('M'); | ||
| 565 | t.eq0 = ~0; | ||
| 566 | scrl->scroll(t, but); | ||
| 567 | t.w.unlock(); | ||
| 568 | } | ||
| 569 | bflush(); | ||
| 570 | row.qlock.unlock(); | ||
| 571 | break; | ||
| 572 | } | ||
| 573 | if(mouse.xy.in(t.scrollr)){ | ||
| 574 | if(but){ | ||
| 575 | if(t.what == Columntag) | ||
| 576 | row.dragcol(t.col); | ||
| 577 | else if(t.what == Tag){ | ||
| 578 | t.col.dragwin(t.w, but); | ||
| 579 | if(t.w != nil) | ||
| 580 | barttext = t.w.body; | ||
| 581 | } | ||
| 582 | if(t.col != nil) | ||
| 583 | activecol = t.col; | ||
| 584 | } | ||
| 585 | bflush(); | ||
| 586 | row.qlock.unlock(); | ||
| 587 | break; | ||
| 588 | } | ||
| 589 | if(mouse.buttons){ | ||
| 590 | if(w != nil) | ||
| 591 | w.lock('M'); | ||
| 592 | t.eq0 = ~0; | ||
| 593 | if(w != nil) | ||
| 594 | w.commit(t); | ||
| 595 | else | ||
| 596 | t.commit(TRUE); | ||
| 597 | if(mouse.buttons & 1){ | ||
| 598 | t.select(0); | ||
| 599 | if(w != nil) | ||
| 600 | w.settag(); | ||
| 601 | argtext = t; | ||
| 602 | seltext = t; | ||
| 603 | if(t.col != nil) | ||
| 604 | activecol = t.col; # button 1 only | ||
| 605 | if(t.w != nil && t == t.w.body) | ||
| 606 | dat->activewin = t.w; | ||
| 607 | }else if(mouse.buttons & 2){ | ||
| 608 | (ok, argt, q0, q1) = t.select2(q0, q1); | ||
| 609 | if(ok) | ||
| 610 | exec->execute(t, q0, q1, FALSE, argt); | ||
| 611 | }else if(mouse.buttons & 4){ | ||
| 612 | (ok, q0, q1) = t.select3(q0, q1); | ||
| 613 | if(ok) | ||
| 614 | look->look3(t, q0, q1, FALSE); | ||
| 615 | } | ||
| 616 | if(w != nil) | ||
| 617 | w.unlock(); | ||
| 618 | bflush(); | ||
| 619 | row.qlock.unlock(); | ||
| 620 | break; | ||
| 621 | } | ||
| 622 | m = <- cplumb => | ||
| 623 | if (m.kind == "text") { | ||
| 624 | attrs := plumbmsg->string2attrs(m.attr); | ||
| 625 | (found, act) := plumbmsg->lookup(attrs, "action"); | ||
| 626 | if (!found || act == nil || act == "showfile") | ||
| 627 | look->plumblook(m); | ||
| 628 | else if (act == "showdata") | ||
| 629 | look->plumbshow(m); | ||
| 630 | } | ||
| 631 | bflush(); | ||
| 632 | } | ||
| 633 | } | ||
| 634 | } | ||
| 635 | exception{ | ||
| 636 | * => | ||
| 637 | shutdown(utils->getexc()); | ||
| 638 | raise; | ||
| 639 | # acmeexit(nil); | ||
| 640 | } | ||
| 641 | } | ||
| 642 | |||
| 643 | # list of processes that have exited but we have not heard of yet | ||
| 644 | Pid : adt { | ||
| 645 | pid : int; | ||
| 646 | msg : string; | ||
| 647 | next : cyclic ref Pid; | ||
| 648 | }; | ||
| 649 | |||
| 650 | waittask() | ||
| 651 | { | ||
| 652 | status : string; | ||
| 653 | c, lc : ref Command; | ||
| 654 | pid : int; | ||
| 655 | found : int; | ||
| 656 | cmd : string; | ||
| 657 | err : string; | ||
| 658 | t : ref Text; | ||
| 659 | pids : ref Pid; | ||
| 660 | |||
| 661 | waittid = sys->pctl(0, nil); | ||
| 662 | command = nil; | ||
| 663 | for(;;){ | ||
| 664 | alt{ | ||
| 665 | err = <-cerr => | ||
| 666 | row.qlock.lock(); | ||
| 667 | warning(nil, err); | ||
| 668 | err = nil; | ||
| 669 | bflush(); | ||
| 670 | row.qlock.unlock(); | ||
| 671 | break; | ||
| 672 | cmd = <-ckill => | ||
| 673 | found = FALSE; | ||
| 674 | for(c=command; c != nil; c=c.next){ | ||
| 675 | # -1 for blank | ||
| 676 | if(c.name[0:len c.name - 1] == cmd){ | ||
| 677 | if(postnote(PNGROUP, waittid, c.pid, "kill") < 0) | ||
| 678 | warning(nil, sprint("kill %s: %r\n", cmd)); | ||
| 679 | found = TRUE; | ||
| 680 | } | ||
| 681 | } | ||
| 682 | if(!found) | ||
| 683 | warning(nil, sprint("Kill: no process %s\n", cmd)); | ||
| 684 | cmd = nil; | ||
| 685 | break; | ||
| 686 | status = <-cwait => | ||
| 687 | pid = int status; | ||
| 688 | lc = nil; | ||
| 689 | for(c=command; c != nil; c=c.next){ | ||
| 690 | if(c.pid == pid){ | ||
| 691 | if(lc != nil) | ||
| 692 | lc.next = c.next; | ||
| 693 | else | ||
| 694 | command = c.next; | ||
| 695 | break; | ||
| 696 | } | ||
| 697 | lc = c; | ||
| 698 | } | ||
| 699 | row.qlock.lock(); | ||
| 700 | t = row.tag; | ||
| 701 | t.commit(TRUE); | ||
| 702 | if(c == nil){ | ||
| 703 | # warning(nil, sprint("unknown child pid %d\n", pid)); | ||
| 704 | p := ref Pid; | ||
| 705 | p.pid = pid; | ||
| 706 | p.msg = status; | ||
| 707 | p.next = pids; | ||
| 708 | pids = p; | ||
| 709 | } | ||
| 710 | else{ | ||
| 711 | if(look->search(t, c.name, len c.name)){ | ||
| 712 | t.delete(t.q0, t.q1, TRUE); | ||
| 713 | t.setselect(0, 0); | ||
| 714 | } | ||
| 715 | if(status[len status - 1] != ':') | ||
| 716 | warning(c.md, sprint("%s\n", status)); | ||
| 717 | bflush(); | ||
| 718 | } | ||
| 719 | row.qlock.unlock(); | ||
| 720 | if(c != nil){ | ||
| 721 | if(c.iseditcmd) | ||
| 722 | cedit <- = 0; | ||
| 723 | fsys->fsysdelid(c.md); | ||
| 724 | c = nil; | ||
| 725 | } | ||
| 726 | break; | ||
| 727 | c = <-ccommand => | ||
| 728 | lastp : ref Pid = nil; | ||
| 729 | for(p := pids; p != nil; p = p.next){ | ||
| 730 | if(p.pid == c.pid){ | ||
| 731 | status = p.msg; | ||
| 732 | if(status[len status - 1] != ':') | ||
| 733 | warning(c.md, sprint("%s\n", status)); | ||
| 734 | if(lastp == nil) | ||
| 735 | pids = p.next; | ||
| 736 | else | ||
| 737 | lastp.next = p.next; | ||
| 738 | if(c.iseditcmd) | ||
| 739 | cedit <- = 0; | ||
| 740 | fsys->fsysdelid(c.md); | ||
| 741 | c = nil; | ||
| 742 | break; | ||
| 743 | } | ||
| 744 | lastp = p; | ||
| 745 | } | ||
| 746 | c.next = command; | ||
| 747 | command = c; | ||
| 748 | row.qlock.lock(); | ||
| 749 | t = row.tag; | ||
| 750 | t.commit(TRUE); | ||
| 751 | t.insert(0, c.name, len c.name, TRUE, 0); | ||
| 752 | t.setselect(0, 0); | ||
| 753 | bflush(); | ||
| 754 | row.qlock.unlock(); | ||
| 755 | break; | ||
| 756 | } | ||
| 757 | } | ||
| 758 | } | ||
| 759 | |||
| 760 | xfidalloctask() | ||
| 761 | { | ||
| 762 | xfree, x : ref Xfid; | ||
| 763 | |||
| 764 | xfidalloctid = sys->pctl(0, nil); | ||
| 765 | xfree = nil; | ||
| 766 | for(;;){ | ||
| 767 | alt{ | ||
| 768 | <-cxfidalloc => | ||
| 769 | x = xfree; | ||
| 770 | if(x != nil) | ||
| 771 | xfree = x.next; | ||
| 772 | else{ | ||
| 773 | x = xfidm->newxfid(); | ||
| 774 | x.c = chan of int; | ||
| 775 | spawn x.ctl(); | ||
| 776 | } | ||
| 777 | cxfidalloc <-= x; | ||
| 778 | break; | ||
| 779 | x = <-cxfidfree => | ||
| 780 | x.next = xfree; | ||
| 781 | xfree = x; | ||
| 782 | break; | ||
| 783 | } | ||
| 784 | } | ||
| 785 | } | ||
| 786 | |||
| 787 | frgetmouse() | ||
| 788 | { | ||
| 789 | bflush(); | ||
| 790 | *mouse = *<-cmouse; | ||
| 791 | } | ||
| 792 | |||
| 793 | waitproc(pid : int, sync: chan of int) | ||
| 794 | { | ||
| 795 | fd : ref Sys->FD; | ||
| 796 | n : int; | ||
| 797 | |||
| 798 | if (waitpid0 == 0) | ||
| 799 | waitpid0 = sys->pctl(0, nil); | ||
| 800 | else | ||
| 801 | waitpid1 = sys->pctl(0, nil); | ||
| 802 | sys->pctl(Sys->FORKFD, nil); | ||
| 803 | # w := sprint("/prog/%d/wait", pid); | ||
| 804 | w := sprint("#p/%d/wait", pid); | ||
| 805 | fd = sys->open(w, Sys->OREAD); | ||
| 806 | if (fd == nil) | ||
| 807 | error("fd == nil in waitproc"); | ||
| 808 | sync <-= 0; | ||
| 809 | buf := array[Sys->WAITLEN] of byte; | ||
| 810 | status := ""; | ||
| 811 | for(;;){ | ||
| 812 | if ((n = sys->read(fd, buf, len buf))<0) | ||
| 813 | error("bad read in waitproc"); | ||
| 814 | status = string buf[0:n]; | ||
| 815 | cwait <-= status; | ||
| 816 | } | ||
| 817 | } | ||
| 818 | |||
| 819 | get(fix : int, save : int, setfont : int, name : string) : ref Reffont | ||
| 820 | { | ||
| 821 | r : ref Reffont; | ||
| 822 | f : ref Font; | ||
| 823 | i : int; | ||
| 824 | |||
| 825 | r = nil; | ||
| 826 | if(name == nil){ | ||
| 827 | name = fontnames[fix]; | ||
| 828 | r = reffonts[fix]; | ||
| 829 | } | ||
| 830 | if(r == nil){ | ||
| 831 | for(i=0; i<nfontcache; i++) | ||
| 832 | if(name == fontcache[i].f.name){ | ||
| 833 | r = fontcache[i]; | ||
| 834 | break; | ||
| 835 | } | ||
| 836 | if (i >= nfontcache) { | ||
| 837 | f = Font.open(display, name); | ||
| 838 | if(f == nil){ | ||
| 839 | warning(nil, sprint("can't open font file %s: %r\n", name)); | ||
| 840 | return nil; | ||
| 841 | } | ||
| 842 | r = ref Reffont; | ||
| 843 | r.r = Ref.init(); | ||
| 844 | r.f = f; | ||
| 845 | ofc := fontcache; | ||
| 846 | fontcache = array[nfontcache+1] of ref Reffont; | ||
| 847 | fontcache[0:] = ofc[0:nfontcache]; | ||
| 848 | ofc = nil; | ||
| 849 | fontcache[nfontcache++] = r; | ||
| 850 | } | ||
| 851 | } | ||
| 852 | if(save){ | ||
| 853 | r.r.inc(); | ||
| 854 | if(reffonts[fix] != nil) | ||
| 855 | reffonts[fix].close(); | ||
| 856 | reffonts[fix] = r; | ||
| 857 | fontnames[fix] = name; | ||
| 858 | } | ||
| 859 | if(setfont){ | ||
| 860 | reffont.f = r.f; | ||
| 861 | r.r.inc(); | ||
| 862 | reffonts[0].close(); | ||
| 863 | font = r.f; | ||
| 864 | reffonts[0] = r; | ||
| 865 | r.r.inc(); | ||
| 866 | iconinit(); | ||
| 867 | } | ||
| 868 | r.r.inc(); | ||
| 869 | return r; | ||
| 870 | } | ||
| 871 | |||
| 872 | close(r : ref Reffont) | ||
| 873 | { | ||
| 874 | i : int; | ||
| 875 | |||
| 876 | if(r.r.dec() == 0){ | ||
| 877 | for(i=0; i<nfontcache; i++) | ||
| 878 | if(r == fontcache[i]) | ||
| 879 | break; | ||
| 880 | if(i >= nfontcache) | ||
| 881 | warning(nil, "internal error: can't find font in cache\n"); | ||
| 882 | else{ | ||
| 883 | fontcache[i:] = fontcache[i+1:nfontcache]; | ||
| 884 | nfontcache--; | ||
| 885 | } | ||
| 886 | r.f = nil; | ||
| 887 | r = nil; | ||
| 888 | } | ||
| 889 | } | ||
| 890 | |||
| 891 | arrowbits := array[64] of { | ||
| 892 | byte 16rFF, byte 16rE0, byte 16rFF, byte 16rE0, | ||
| 893 | byte 16rFF, byte 16rC0, byte 16rFF, byte 16r00, | ||
| 894 | byte 16rFF, byte 16r00, byte 16rFF, byte 16r80, | ||
| 895 | byte 16rFF, byte 16rC0, byte 16rFF, byte 16rE0, | ||
| 896 | byte 16rE7, byte 16rF0, byte 16rE3, byte 16rF8, | ||
| 897 | byte 16rC1, byte 16rFC, byte 16r00, byte 16rFE, | ||
| 898 | byte 16r00, byte 16r7F, byte 16r00, byte 16r3E, | ||
| 899 | byte 16r00, byte 16r1C, byte 16r00, byte 16r08, | ||
| 900 | |||
| 901 | byte 16r00, byte 16r00, byte 16r7F, byte 16rC0, | ||
| 902 | byte 16r7F, byte 16r00, byte 16r7C, byte 16r00, | ||
| 903 | byte 16r7E, byte 16r00, byte 16r7F, byte 16r00, | ||
| 904 | byte 16r6F, byte 16r80, byte 16r67, byte 16rC0, | ||
| 905 | byte 16r43, byte 16rE0, byte 16r41, byte 16rF0, | ||
| 906 | byte 16r00, byte 16rF8, byte 16r00, byte 16r7C, | ||
| 907 | byte 16r00, byte 16r3E, byte 16r00, byte 16r1C, | ||
| 908 | byte 16r00, byte 16r08, byte 16r00, byte 16r00, | ||
| 909 | }; | ||
| 910 | |||
| 911 | # outer boundary of width 1 is white | ||
| 912 | # next boundary of width 3 is black | ||
| 913 | # next boundary of width 1 is white | ||
| 914 | # inner boundary of width 4 is transparent | ||
| 915 | boxbits := array[64] of { | ||
| 916 | byte 16rFF, byte 16rFF, byte 16rFF, byte 16rFF, | ||
| 917 | byte 16rFF, byte 16rFF, byte 16rFF, byte 16rFF, | ||
| 918 | byte 16rFF, byte 16rFF, byte 16rF8, byte 16r1F, | ||
| 919 | byte 16rF8, byte 16r1F, byte 16rF8, byte 16r1F, | ||
| 920 | byte 16rF8, byte 16r1F, byte 16rF8, byte 16r1F, | ||
| 921 | byte 16rF8, byte 16r1F, byte 16rFF, byte 16rFF, | ||
| 922 | byte 16rFF, byte 16rFF, byte 16rFF, byte 16rFF, | ||
| 923 | byte 16rFF, byte 16rFF, byte 16rFF, byte 16rFF, | ||
| 924 | |||
| 925 | |||
| 926 | byte 16r00, byte 16r00, byte 16r7F, byte 16rFE, | ||
| 927 | byte 16r7F, byte 16rFE, byte 16r7F, byte 16rFE, | ||
| 928 | byte 16r70, byte 16r0E, byte 16r70, byte 16r0E, | ||
| 929 | byte 16r70, byte 16r0E, byte 16r70, byte 16r0E, | ||
| 930 | byte 16r70, byte 16r0E, byte 16r70, byte 16r0E, | ||
| 931 | byte 16r70, byte 16r0E, byte 16r70, byte 16r0E, | ||
| 932 | byte 16r7F, byte 16rFE, byte 16r7F, byte 16rFE, | ||
| 933 | byte 16r7F, byte 16rFE, byte 16r00, byte 16r00, | ||
| 934 | }; | ||
| 935 | |||
| 936 | iconinit() | ||
| 937 | { | ||
| 938 | r : Rect; | ||
| 939 | |||
| 940 | # Blue | ||
| 941 | tagcols = array[NCOL] of ref Draw->Image; | ||
| 942 | tagcols[BACK] = display.colormix(Draw->Palebluegreen, Draw->White); | ||
| 943 | tagcols[HIGH] = display.color(Draw->Palegreygreen); | ||
| 944 | tagcols[BORD] = display.color(Draw->Purpleblue); | ||
| 945 | tagcols[TEXT] = black; | ||
| 946 | tagcols[HTEXT] = black; | ||
| 947 | |||
| 948 | # Yellow | ||
| 949 | textcols = array[NCOL] of ref Draw->Image; | ||
| 950 | textcols[BACK] = display.colormix(Draw->Paleyellow, Draw->White); | ||
| 951 | textcols[HIGH] = display.color(Draw->Darkyellow); | ||
| 952 | textcols[BORD] = display.color(Draw->Yellowgreen); | ||
| 953 | textcols[TEXT] = black; | ||
| 954 | textcols[HTEXT] = black; | ||
| 955 | |||
| 956 | if(button != nil) | ||
| 957 | button = modbutton = colbutton = nil; | ||
| 958 | |||
| 959 | r = ((0, 0), (Dat->Scrollwid+2, font.height+1)); | ||
| 960 | button = balloc(r, mainwin.chans, Draw->White); | ||
| 961 | draw(button, r, tagcols[BACK], nil, r.min); | ||
| 962 | r.max.x -= 2; | ||
| 963 | draw(button, r, tagcols[BORD], nil, (0, 0)); | ||
| 964 | r = r.inset(2); | ||
| 965 | draw(button, r, tagcols[BACK], nil, (0, 0)); | ||
| 966 | |||
| 967 | r = button.r; | ||
| 968 | modbutton = balloc(r, mainwin.chans, Draw->White); | ||
| 969 | draw(modbutton, r, tagcols[BACK], nil, r.min); | ||
| 970 | r.max.x -= 2; | ||
| 971 | draw(modbutton, r, tagcols[BORD], nil, (0, 0)); | ||
| 972 | r = r.inset(2); | ||
| 973 | draw(modbutton, r, display.rgb(16r00, 16r00, 16r99), nil, (0, 0)); # was DMedblue | ||
| 974 | |||
| 975 | r = button.r; | ||
| 976 | colbutton = balloc(r, mainwin.chans, Draw->White); | ||
| 977 | draw(colbutton, r, tagcols[BACK], nil, r.min); | ||
| 978 | r.max.x -= 2; | ||
| 979 | draw(colbutton, r, tagcols[BORD], nil, (0, 0)); | ||
| 980 | |||
| 981 | # arrowcursor = ref Cursor((-1, -1), (16, 32), arrowbits); | ||
| 982 | boxcursor = ref Cursor((-7, -7), (16, 32), boxbits); | ||
| 983 | |||
| 984 | but2col = display.rgb(16raa, 16r00, 16r00); | ||
| 985 | but3col = display.rgb(16r00, 16r66, 16r00); | ||
| 986 | but2colt = white; | ||
| 987 | but3colt = white; | ||
| 988 | |||
| 989 | graph->cursorswitch(arrowcursor); | ||
| 990 | } | ||
| 991 | |||
| 992 | colrec : adt { | ||
| 993 | name : string; | ||
| 994 | image : ref Image; | ||
| 995 | }; | ||
| 996 | |||
| 997 | coltab : array of colrec; | ||
| 998 | |||
| 999 | cinit() | ||
| 1000 | { | ||
| 1001 | coltab = array[6] of colrec; | ||
| 1002 | coltab[0].name = "yellow"; coltab[0].image = yellow; | ||
| 1003 | coltab[1].name = "green"; coltab[1].image = green; | ||
| 1004 | coltab[2].name = "red"; coltab[2].image = red; | ||
| 1005 | coltab[3].name = "blue"; coltab[3].image = blue; | ||
| 1006 | coltab[4].name = "black"; coltab[4].image = black; | ||
| 1007 | coltab[5].name = "white"; coltab[5].image = white; | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | col(s : string, n : int) : int | ||
| 1011 | { | ||
| 1012 | return ((s[n]-'0') << 4) | (s[n+1]-'0'); | ||
| 1013 | } | ||
| 1014 | |||
| 1015 | rgb(s : string, n : int) : (int, int, int) | ||
| 1016 | { | ||
| 1017 | return (col(s, n), col(s, n+2), col(s, n+4)); | ||
| 1018 | } | ||
| 1019 | |||
| 1020 | cenv(s : string, t : string, but : int, i : ref Image) : ref Image | ||
| 1021 | { | ||
| 1022 | c := utils->getenv("acme-" + s + "-" + t + "-" + string but); | ||
| 1023 | if (c == nil) | ||
| 1024 | c = utils->getenv("acme-" + s + "-" + string but); | ||
| 1025 | if (c == nil && but != 0) | ||
| 1026 | c = utils->getenv("acme-" + s); | ||
| 1027 | if (c != nil) { | ||
| 1028 | if (c[0] == '#' && len c >= 7) { | ||
| 1029 | (r1, g1, b1) := rgb(c, 1); | ||
| 1030 | if (len c >= 15 && c[7] == '/' && c[8] == '#') { | ||
| 1031 | (r2, g2, b2) := rgb(c, 9); | ||
| 1032 | return display.colormix((r1<<24)|(g1<<16)|(b1<<8)|16rFF, (r2<<24)|(g2<<16)|(b2<<8)|16rFF); | ||
| 1033 | } | ||
| 1034 | return display.color((r1<<24)|(g1<<16)|(b1<<8)|16rFF); | ||
| 1035 | } | ||
| 1036 | for (j := 0; j < len c; j++) | ||
| 1037 | if (c[j] >= 'A' && c[j] <= 'Z') | ||
| 1038 | c[j] += 'a'-'A'; | ||
| 1039 | for (j = 0; j < len coltab; j++) | ||
| 1040 | if (c == coltab[j].name) | ||
| 1041 | return coltab[j].image; | ||
| 1042 | } | ||
| 1043 | return i; | ||
| 1044 | } | ||
| 1045 | |||
| 1046 | usercolinit() | ||
| 1047 | { | ||
| 1048 | cinit(); | ||
| 1049 | textcols[TEXT] = cenv("fg", "text", 0, textcols[TEXT]); | ||
| 1050 | textcols[BACK] = cenv("bg", "text", 0, textcols[BACK]); | ||
| 1051 | textcols[HTEXT] = cenv("fg", "text", 1, textcols[HTEXT]); | ||
| 1052 | textcols[HIGH] = cenv("bg", "text", 1, textcols[HIGH]); | ||
| 1053 | but2colt= cenv("fg", "text", 2, but2colt); | ||
| 1054 | but2col = cenv("bg", "text", 2, but2col); | ||
| 1055 | but3colt = cenv("fg", "text", 3, but3colt); | ||
| 1056 | but3col = cenv("bg", "text", 3, but3col); | ||
| 1057 | tagcols[TEXT] = cenv("fg", "tag", 0, tagcols[TEXT]); | ||
| 1058 | tagcols[BACK] = cenv("bg", "tag", 0, tagcols[BACK]); | ||
| 1059 | tagcols[HTEXT] = cenv("fg", "tag", 1, tagcols[HTEXT]); | ||
| 1060 | tagcols[HIGH] = cenv("bg", "tag", 1, tagcols[HIGH]); | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | getsnarf() | ||
| 1064 | { | ||
| 1065 | # return; | ||
| 1066 | fd := sys->open("/chan/snarf", sys->OREAD); | ||
| 1067 | if(fd == nil) | ||
| 1068 | return; | ||
| 1069 | snarfbuf.reset(); | ||
| 1070 | snarfbuf.loadx(0, fd); | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | putsnarf() | ||
| 1074 | { | ||
| 1075 | n : int; | ||
| 1076 | |||
| 1077 | # return; | ||
| 1078 | if(snarfbuf.nc == 0) | ||
| 1079 | return; | ||
| 1080 | fd := sys->open("/chan/snarf", sys->OWRITE); | ||
| 1081 | if(fd == nil) | ||
| 1082 | return; | ||
| 1083 | for(i:=0; i<snarfbuf.nc; i+=n){ | ||
| 1084 | n = snarfbuf.nc-i; | ||
| 1085 | if(n >= NSnarf) | ||
| 1086 | n = NSnarf; | ||
| 1087 | snarfbuf.read(i, snarfrune, 0, n); | ||
| 1088 | sys->fprint(fd, "%s", snarfrune.s[0:n]); | ||
| 1089 | } | ||
| 1090 | } | ||
| 1091 | |||
| 1092 | plumbpid : int; | ||
| 1093 | |||
| 1094 | plumbproc() | ||
| 1095 | { | ||
| 1096 | plumbpid = sys->pctl(0, nil); | ||
| 1097 | for(;;){ | ||
| 1098 | msg := Msg.recv(); | ||
| 1099 | if(msg == nil){ | ||
| 1100 | sys->print("Acme: can't read /chan/plumb.edit: %r\n"); | ||
| 1101 | plumbpid = 0; | ||
| 1102 | plumbed = 0; | ||
| 1103 | return; | ||
| 1104 | } | ||
| 1105 | if(msg.kind != "text"){ | ||
| 1106 | sys->print("Acme: can't interpret '%s' kind of message\n", msg.kind); | ||
| 1107 | continue; | ||
| 1108 | } | ||
| 1109 | # sys->print("msg %s\n", string msg.data); | ||
| 1110 | cplumb <-= msg; | ||
| 1111 | } | ||
| 1112 | } | ||
| @@ -0,0 +1,32 @@ | |||
| 1 | Acme : module { | ||
| 2 | PATH : con "/dis/acme.dis"; | ||
| 3 | |||
| 4 | RELEASECOPY : con 1; | ||
| 5 | |||
| 6 | M_LBUT : con 1; | ||
| 7 | M_MBUT : con 2; | ||
| 8 | M_RBUT : con 4; | ||
| 9 | M_TBS : con 8; | ||
| 10 | M_PLUMB : con 16; | ||
| 11 | M_QUIT : con 32; | ||
| 12 | M_HELP : con 64; | ||
| 13 | M_RESIZE : con 128; | ||
| 14 | M_DOUBLE : con 256; | ||
| 15 | |||
| 16 | textcols, tagcols : array of ref Draw->Image; | ||
| 17 | but2col, but3col, but2colt, but3colt : ref Draw->Image; | ||
| 18 | |||
| 19 | acmectxt : ref Draw->Context; | ||
| 20 | keyboardpid, mousepid, timerpid, fsyspid : int; | ||
| 21 | fontnames : array of string; | ||
| 22 | wdir : string; | ||
| 23 | |||
| 24 | init : fn(ctxt : ref Draw->Context, argv : list of string); | ||
| 25 | timing : fn(s : string); | ||
| 26 | frgetmouse : fn(); | ||
| 27 | get : fn(p, q, r : int, b : string) : ref Dat->Reffont; | ||
| 28 | close : fn(r : ref Dat->Reffont); | ||
| 29 | acmeexit : fn(err : string); | ||
| 30 | getsnarf : fn(); | ||
| 31 | putsnarf : fn(); | ||
| 32 | }; | ||
| @@ -0,0 +1,2 @@ | |||
| 1 | Acid pid | ||
| 2 | Acid -l alef -l symsfile pid | ||
| @@ -0,0 +1,24 @@ | |||
| 1 | <../../../../mkconfig | ||
| 2 | |||
| 3 | BIN=$ROOT/acme/acid | ||
| 4 | |||
| 5 | DIRS=\ | ||
| 6 | src\ | ||
| 7 | |||
| 8 | TARG=\ | ||
| 9 | guide\ | ||
| 10 | readme\ | ||
| 11 | |||
| 12 | BINTARG=${TARG:%=$BIN/%} | ||
| 13 | |||
| 14 | all:V: $TARG | ||
| 15 | |||
| 16 | install:V: $BINTARG | ||
| 17 | |||
| 18 | $BIN/guide : guide | ||
| 19 | rm -f $BIN/guide && cp guide $BIN/guide | ||
| 20 | |||
| 21 | $BIN/readme : readme | ||
| 22 | rm -f $BIN/readme && cp readme $BIN/readme | ||
| 23 | |||
| 24 | <$ROOT/mkfiles/mksubdirs | ||
| @@ -0,0 +1,12 @@ | |||
| 1 | Capital A Acid is a rudimentary acme interface to the debugger acid. | ||
| 2 | It uses a win to provide an interactive window for acid. In that window, | ||
| 3 | a couple of extra acme-specific features are enabled: | ||
| 4 | |||
| 5 | w(command) | ||
| 6 | runs the command and places its output in a new window. | ||
| 7 | e.g. w(lstk()) places the stack trace in a distinct window. | ||
| 8 | |||
| 9 | Also, in any such window, text executed with button 2 is | ||
| 10 | presented as input to acid in the main Acid window. Thus, for | ||
| 11 | example, one may evaluate variables presented in a stack trace | ||
| 12 | by `executing' it with button 2. | ||
| @@ -0,0 +1,31 @@ | |||
| 1 | implement Acid; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "sh.m"; | ||
| 6 | |||
| 7 | Acid : module { | ||
| 8 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 9 | }; | ||
| 10 | |||
| 11 | init(ctxt : ref Draw->Context, argl : list of string) | ||
| 12 | { | ||
| 13 | sys := load Sys Sys->PATH; | ||
| 14 | stderr := sys->fildes(2); | ||
| 15 | if (len argl < 2) { | ||
| 16 | sys->fprint(stderr, "usage : Acid pid\n"); | ||
| 17 | return; | ||
| 18 | } | ||
| 19 | cmd := "/acme/dis/win"; | ||
| 20 | file := cmd + ".dis"; | ||
| 21 | c := load Command file; | ||
| 22 | if(c == nil) { | ||
| 23 | sys->fprint(stderr, "%s: %r\n", cmd); | ||
| 24 | return; | ||
| 25 | } | ||
| 26 | argl = "-l" :: argl; | ||
| 27 | argl = "acid" :: argl; | ||
| 28 | argl = "/acme/dis/Acid0" :: argl; | ||
| 29 | argl = cmd :: argl; | ||
| 30 | c->init(ctxt, argl); | ||
| 31 | } | ||
| @@ -0,0 +1,86 @@ | |||
| 1 | implement Acidb; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | |||
| 7 | sys : Sys; | ||
| 8 | bufio : Bufio; | ||
| 9 | |||
| 10 | FD : import sys; | ||
| 11 | Iobuf : import bufio; | ||
| 12 | |||
| 13 | Acidb : module { | ||
| 14 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 15 | }; | ||
| 16 | |||
| 17 | init(nil : ref Draw->Context, nil : list of string) | ||
| 18 | { | ||
| 19 | sys = load Sys Sys->PATH; | ||
| 20 | bufio = load Bufio Bufio->PATH; | ||
| 21 | # TBS main(argl); | ||
| 22 | } | ||
| 23 | |||
| 24 | False : con 0; | ||
| 25 | True : con 1; | ||
| 26 | |||
| 27 | EVENTSIZE : con 256; | ||
| 28 | |||
| 29 | Event : adt { | ||
| 30 | c1, c2, q0, q1, flag, nb, nr : int; | ||
| 31 | b : array of byte; | ||
| 32 | r : array of int; | ||
| 33 | # TBS byte b[EVENTSIZE*UTFmax+1]; | ||
| 34 | # TBS Rune r[EVENTSIZE+1]; | ||
| 35 | }; | ||
| 36 | |||
| 37 | Win : adt { | ||
| 38 | winid : int; | ||
| 39 | addr : int; | ||
| 40 | body : ref Iobuf; | ||
| 41 | ctl : int; | ||
| 42 | data : int; | ||
| 43 | event : int; | ||
| 44 | buf : array of byte; | ||
| 45 | # TBS byte buf[512]; | ||
| 46 | bufp : int; | ||
| 47 | nbuf : int; | ||
| 48 | |||
| 49 | wnew : fn(w : ref Win); | ||
| 50 | wwritebody : fn(w : ref Win, s : array of byte, n : int); | ||
| 51 | wread : fn(w : ref Win, m : int, n : int, s : array of byte); | ||
| 52 | wclean : fn(w : ref Win); | ||
| 53 | wname : fn(w : ref Win, s : array of byte); | ||
| 54 | wdormant : fn(w : ref Win); | ||
| 55 | wevent : fn(w : ref Win, e : ref Event); | ||
| 56 | wtagwrite : fn(w : ref Win, s : array of byte, n : int); | ||
| 57 | wwriteevent : fn(w : ref Win, e : ref Event); | ||
| 58 | wslave : fn(w : ref Win, c : chan of Event); | ||
| 59 | wreplace : fn(w : ref Win, s : array of byte, b : array of byte, n : int); | ||
| 60 | wselect : fn(w : ref Win, s : array of byte); | ||
| 61 | wdel : fn(w : ref Win, n : int) : int; | ||
| 62 | wreadall : fn(w : ref Win) : (int, array of byte); | ||
| 63 | |||
| 64 | ctlwrite : fn(w : ref Win, s : array of byte); | ||
| 65 | getec : fn(w : ref Win) : int; | ||
| 66 | geten : fn(w : ref Win) : int; | ||
| 67 | geter : fn(w : ref Win, s : array of byte, r : array of int) : int; | ||
| 68 | openfile : fn(w : ref Win, b : array of byte) : int; | ||
| 69 | openbody : fn(w : ref Win, n : int); | ||
| 70 | }; | ||
| 71 | |||
| 72 | Awin : adt { | ||
| 73 | w : Win; | ||
| 74 | |||
| 75 | slave : fn(w : ref Awin, s : array of byte, c : chan of int); | ||
| 76 | new : fn(w : ref Awin, s : array of byte); | ||
| 77 | command : fn(w : ref Awin, s : array of byte) : int; | ||
| 78 | send : fn(w : ref Awin, m : int, s : array of byte, n : int); | ||
| 79 | }; | ||
| 80 | |||
| 81 | srvfd : ref FD; | ||
| 82 | stdin : ref FD; | ||
| 83 | srvenv : array of byte; | ||
| 84 | # TBS byte srvenv[64]; | ||
| 85 | |||
| 86 | srvc : chan of array of byte; | ||
| @@ -0,0 +1,20 @@ | |||
| 1 | <../../../../../mkconfig | ||
| 2 | |||
| 3 | TARG=\ | ||
| 4 | Acid.dis\ | ||
| 5 | Acid0.dis\ | ||
| 6 | # acid.dis\ | ||
| 7 | # awin.dis\ | ||
| 8 | # util.dis\ | ||
| 9 | # win.dis\ | ||
| 10 | |||
| 11 | MODULES=\ | ||
| 12 | |||
| 13 | SYSMODULES=\ | ||
| 14 | sh.m\ | ||
| 15 | sys.m\ | ||
| 16 | draw.m\ | ||
| 17 | |||
| 18 | DISBIN=$ROOT/acme/acid | ||
| 19 | |||
| 20 | <$ROOT/mkfiles/mkdis | ||
| @@ -0,0 +1,5 @@ | |||
| 1 | win | ||
| 2 | new command ... | ||
| 3 | aspell file | ||
| 4 | adiff file1 file2 | ||
| 5 | adict -d oed | ||
| @@ -0,0 +1,24 @@ | |||
| 1 | <../../../../mkconfig | ||
| 2 | |||
| 3 | BIN=$ROOT/acme/bin | ||
| 4 | |||
| 5 | DIRS=\ | ||
| 6 | src\ | ||
| 7 | |||
| 8 | TARG=\ | ||
| 9 | guide\ | ||
| 10 | readme\ | ||
| 11 | |||
| 12 | BINTARG=${TARG:%=$BIN/%} | ||
| 13 | |||
| 14 | all:V: $TARG | ||
| 15 | |||
| 16 | install:V: $BINTARG | ||
| 17 | |||
| 18 | $BIN/guide : guide | ||
| 19 | rm -f $BIN/guide && cp guide $BIN/guide | ||
| 20 | |||
| 21 | $BIN/readme : readme | ||
| 22 | rm -f $BIN/readme && cp readme $BIN/readme | ||
| 23 | |||
| 24 | <$ROOT/mkfiles/mksubdirs | ||
| @@ -0,0 +1,25 @@ | |||
| 1 | This directory and its subdirectory $cputype are always mounted at | ||
| 2 | the end of /bin for programs run from acme. They hold a collection | ||
| 3 | of small acme-specific applications: | ||
| 4 | |||
| 5 | win [command] | ||
| 6 | Create an acme window to serve as a terminal, analogous | ||
| 7 | to xterm. By default, it runs the shell, rc, but it works with | ||
| 8 | any interactive program, e.g. hoc. Within the window, | ||
| 9 | commands executed with button 2 are 'executed' by sending | ||
| 10 | their text to the standard input of the command, appending | ||
| 11 | a newline if necessary. | ||
| 12 | new command | ||
| 13 | Run the non-interactive command, placing its standard and | ||
| 14 | diagnostic output in a new window. | ||
| 15 | aspell file | ||
| 16 | Run spell on the file, labeling the output with addresses so | ||
| 17 | misspelled words can be found in context using button 3. | ||
| 18 | adiff file1 file2 | ||
| 19 | Run diff on the files, labeling the output with addresses so | ||
| 20 | changes can be found in context using button 3. | ||
| 21 | adict | ||
| 22 | Interactive version of dict(1). Button 3 looks up words and | ||
| 23 | may be applied to any word in any adict window. | ||
| 24 | When a word has multiple definitions, indicate the number | ||
| 25 | (as in acme Mail) to disambiguate. | ||
| @@ -0,0 +1,155 @@ | |||
| 1 | implement Adiff; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "sh.m"; | ||
| 6 | include "workdir.m"; | ||
| 7 | include "bufio.m"; | ||
| 8 | |||
| 9 | Adiff : module { | ||
| 10 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 11 | }; | ||
| 12 | |||
| 13 | sys : Sys; | ||
| 14 | |||
| 15 | Context : import Draw; | ||
| 16 | OREAD, OWRITE, QTDIR, FD, FORKFD, open, read, write, sprint, fprint, stat, fildes, dup, pctl : import sys; | ||
| 17 | |||
| 18 | init(ctxt : ref Context, argl : list of string) | ||
| 19 | { | ||
| 20 | sys = load Sys Sys->PATH; | ||
| 21 | workdir := load Workdir Workdir->PATH; | ||
| 22 | stderr := fildes(2); | ||
| 23 | if (len argl != 3) { | ||
| 24 | fprint(stderr, "usage: adiff file1 file2\n"); | ||
| 25 | return; | ||
| 26 | } | ||
| 27 | ncfd := open("/chan/new/ctl", OREAD); | ||
| 28 | if (ncfd == nil) { | ||
| 29 | fprint(stderr, "cannot open ctl file\n"); | ||
| 30 | return; | ||
| 31 | } | ||
| 32 | b := array[128] of byte; | ||
| 33 | n := read(ncfd, b, len b); | ||
| 34 | id := string int string b[0:n]; | ||
| 35 | f1 := hd tl argl; | ||
| 36 | f2 := hd tl tl argl; | ||
| 37 | (ok1, d1) := stat(f1); | ||
| 38 | if (ok1 < 0) { | ||
| 39 | fprint(stderr, "cannot stat %s\n", f1); | ||
| 40 | return; | ||
| 41 | } | ||
| 42 | (ok2, d2) := stat(f2); | ||
| 43 | if (ok2 < 0) { | ||
| 44 | fprint(stderr, "cannot stat %s\n", f2); | ||
| 45 | return; | ||
| 46 | } | ||
| 47 | if (d1.qid.qtype & QTDIR) | ||
| 48 | f1 = f1 + "/" + basename(f2); | ||
| 49 | else if (d2.qid.qtype & QTDIR) | ||
| 50 | f2 = f2 + "/" + basename(f1); | ||
| 51 | buf := "/chan/" + id + "/ctl"; | ||
| 52 | icfd := open(buf, OWRITE); | ||
| 53 | if (icfd == nil) { | ||
| 54 | fprint(stderr, "cannot open control file\n"); | ||
| 55 | return; | ||
| 56 | } | ||
| 57 | buf = "name " + workdir->init() + "/-diff-" + f1 + "\n"; | ||
| 58 | b = array of byte buf; | ||
| 59 | write(icfd, b, len b); | ||
| 60 | |||
| 61 | fds := array[2] of ref FD; | ||
| 62 | if (sys->pipe(fds) < 0) { | ||
| 63 | fprint(stderr, "can't pipe\n"); | ||
| 64 | return; | ||
| 65 | } | ||
| 66 | buf = "/chan/" + id + "/body"; | ||
| 67 | bfd := open(buf, OWRITE); | ||
| 68 | if (bfd == nil) { | ||
| 69 | fprint(stderr, "cannot open body file\n"); | ||
| 70 | return; | ||
| 71 | } | ||
| 72 | spawn diff(fds[1], f1, f2, ctxt); | ||
| 73 | fds[1] = nil; | ||
| 74 | awk(fds[0], bfd, f1, f2); | ||
| 75 | b = array of byte "clean\n"; | ||
| 76 | write(icfd, b, len b); | ||
| 77 | } | ||
| 78 | |||
| 79 | strchr(s : string, c : int) : int | ||
| 80 | { | ||
| 81 | for (i := 0; i < len s; i++) | ||
| 82 | if (s[i] == c) | ||
| 83 | return i; | ||
| 84 | return -1; | ||
| 85 | } | ||
| 86 | |||
| 87 | strchrs(s, pat : string) : int | ||
| 88 | { | ||
| 89 | for (i := 0; i < len s; i++) | ||
| 90 | if (strchr(pat, s[i]) >= 0) | ||
| 91 | return i; | ||
| 92 | return -1; | ||
| 93 | } | ||
| 94 | |||
| 95 | awk(ifd, ofd : ref FD, f1, f2 : string) | ||
| 96 | { | ||
| 97 | bufio := load Bufio Bufio->PATH; | ||
| 98 | Iobuf : import bufio; | ||
| 99 | b := bufio->fopen(ifd, OREAD); | ||
| 100 | while ((s := b.gets('\n')) != nil) { | ||
| 101 | if (s[0] >= '1' && s[0] <= '9') { | ||
| 102 | if ((n := strchrs(s, "acd")) >= 0) | ||
| 103 | s = f1 + ":" + s[0:n] + " " + s[n:n+1] + " " + f2 + ":" + s[n+1:]; | ||
| 104 | } | ||
| 105 | fprint(ofd, "%s", s); | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | diff(ofd : ref FD, f1, f2 : string, ctxt : ref Context) | ||
| 110 | { | ||
| 111 | args : list of string; | ||
| 112 | |||
| 113 | pctl(FORKFD, nil); | ||
| 114 | fd := open("/dev/null", OREAD); | ||
| 115 | dup(fd.fd, 0); | ||
| 116 | fd = nil; | ||
| 117 | dup(ofd.fd, 1); | ||
| 118 | dup(1, 2); | ||
| 119 | ofd = nil; | ||
| 120 | args = nil; | ||
| 121 | args = f2 :: args; | ||
| 122 | args = f1 :: args; | ||
| 123 | args = "diff" :: args; | ||
| 124 | exec("diff", args, ctxt); | ||
| 125 | exit; | ||
| 126 | } | ||
| 127 | |||
| 128 | exec(cmd : string, argl : list of string, ctxt : ref Context) | ||
| 129 | { | ||
| 130 | file := cmd; | ||
| 131 | if(len file<4 || file[len file-4:]!=".dis") | ||
| 132 | file += ".dis"; | ||
| 133 | c := load Command file; | ||
| 134 | if(c == nil) { | ||
| 135 | err := sprint("%r"); | ||
| 136 | if(file[0]!='/' && file[0:2]!="./"){ | ||
| 137 | c = load Command "/dis/"+file; | ||
| 138 | if(c == nil) | ||
| 139 | err = sprint("%r"); | ||
| 140 | } | ||
| 141 | if(c == nil){ | ||
| 142 | fprint(fildes(2), "%s: %s\n", cmd, err); | ||
| 143 | return; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | c->init(ctxt, argl); | ||
| 147 | } | ||
| 148 | |||
| 149 | basename(s : string) : string | ||
| 150 | { | ||
| 151 | for (i := len s -1; i >= 0; --i) | ||
| 152 | if (s[i] == '/') | ||
| 153 | return s[i+1:]; | ||
| 154 | return s; | ||
| 155 | } | ||
| @@ -0,0 +1,46 @@ | |||
| 1 | implement Agrep; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "sh.m"; | ||
| 6 | |||
| 7 | Agrep : module { | ||
| 8 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 9 | }; | ||
| 10 | |||
| 11 | init(ctxt : ref Draw->Context, argl : list of string) | ||
| 12 | { | ||
| 13 | sys := load Sys Sys->PATH; | ||
| 14 | stderr := sys->fildes(2); | ||
| 15 | cmd := "grep"; | ||
| 16 | file := cmd + ".dis"; | ||
| 17 | c := load Command file; | ||
| 18 | if(c == nil) { | ||
| 19 | err := sys->sprint("%r"); | ||
| 20 | if(file[0]!='/' && file[0:2]!="./"){ | ||
| 21 | c = load Command "/dis/"+file; | ||
| 22 | if(c == nil) | ||
| 23 | err = sys->sprint("%r"); | ||
| 24 | } | ||
| 25 | if(c == nil){ | ||
| 26 | sys->fprint(stderr, "%s: %s\n", cmd, err); | ||
| 27 | return; | ||
| 28 | } | ||
| 29 | } | ||
| 30 | argl = tl argl; | ||
| 31 | argl = rev(argl); | ||
| 32 | argl = "/dev/null" :: argl; | ||
| 33 | argl = rev(argl); | ||
| 34 | argl = "-n" :: argl; | ||
| 35 | argl = cmd :: argl; | ||
| 36 | c->init(ctxt, argl); | ||
| 37 | } | ||
| 38 | |||
| 39 | rev(a : list of string) : list of string | ||
| 40 | { | ||
| 41 | b : list of string; | ||
| 42 | |||
| 43 | for ( ; a != nil; a = tl a) | ||
| 44 | b = hd a :: b; | ||
| 45 | return b; | ||
| 46 | } | ||
| @@ -0,0 +1,45 @@ | |||
| 1 | implement Awd; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "workdir.m"; | ||
| 6 | |||
| 7 | Awd : module { | ||
| 8 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 9 | }; | ||
| 10 | |||
| 11 | sys : Sys; | ||
| 12 | workdir : Workdir; | ||
| 13 | |||
| 14 | FD, OWRITE, open, write : import sys; | ||
| 15 | |||
| 16 | init(nil : ref Draw->Context, argl : list of string) | ||
| 17 | { | ||
| 18 | n : int; | ||
| 19 | fd : ref FD; | ||
| 20 | buf, dir, str : string; | ||
| 21 | ab : array of byte; | ||
| 22 | |||
| 23 | sys = load Sys Sys->PATH; | ||
| 24 | workdir = load Workdir Workdir->PATH; | ||
| 25 | fd = open("/dev/acme/ctl", OWRITE); | ||
| 26 | if(fd == nil) | ||
| 27 | exit; | ||
| 28 | dir = workdir->init(); | ||
| 29 | buf = "name " + dir; | ||
| 30 | n = len buf; | ||
| 31 | if(n>0 && buf[n-1] !='/') | ||
| 32 | buf[n++] = '/'; | ||
| 33 | buf[n++] = '-'; | ||
| 34 | if(tl argl != nil) | ||
| 35 | str = hd tl argl; | ||
| 36 | else | ||
| 37 | str = "rc"; | ||
| 38 | buf += str + "\n"; | ||
| 39 | ab = array of byte buf; | ||
| 40 | write(fd, ab, len ab); | ||
| 41 | buf = "dumpdir " + dir + "\n"; | ||
| 42 | ab = array of byte buf; | ||
| 43 | write(fd, ab, len ab); | ||
| 44 | exit; | ||
| 45 | } | ||
| @@ -0,0 +1,70 @@ | |||
| 1 | implement Cd; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "workdir.m"; | ||
| 6 | |||
| 7 | Cd : module { | ||
| 8 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 9 | }; | ||
| 10 | |||
| 11 | sys : Sys; | ||
| 12 | workdir : Workdir; | ||
| 13 | |||
| 14 | FD, OREAD, OWRITE, open, read, write, chdir, fildes, fprint : import sys; | ||
| 15 | |||
| 16 | init(nil : ref Draw->Context, argl : list of string) | ||
| 17 | { | ||
| 18 | n : int; | ||
| 19 | fd, stderr : ref FD; | ||
| 20 | buf, dir, str : string; | ||
| 21 | ab : array of byte; | ||
| 22 | |||
| 23 | sys = load Sys Sys->PATH; | ||
| 24 | stderr = fildes(2); | ||
| 25 | argl = tl argl; | ||
| 26 | if (argl == nil) | ||
| 27 | argl = "/usr/" + user() :: nil; | ||
| 28 | if (tl argl != nil) { | ||
| 29 | fprint(stderr, "Usage: cd [directory]\n"); | ||
| 30 | exit; | ||
| 31 | } | ||
| 32 | if (chdir(hd argl) < 0) { | ||
| 33 | fprint(stderr, "cd: %s: %r\n", hd argl); | ||
| 34 | exit; | ||
| 35 | } | ||
| 36 | |||
| 37 | workdir = load Workdir Workdir->PATH; | ||
| 38 | fd = open("/dev/acme/ctl", OWRITE); | ||
| 39 | if(fd == nil) | ||
| 40 | exit; | ||
| 41 | dir = workdir->init(); | ||
| 42 | buf = "name " + dir; | ||
| 43 | n = len buf; | ||
| 44 | if(n>0 && buf[n-1] !='/') | ||
| 45 | buf[n++] = '/'; | ||
| 46 | buf[n++] = '-'; | ||
| 47 | if(tl argl != nil) | ||
| 48 | str = hd tl argl; | ||
| 49 | else | ||
| 50 | str = "sh"; | ||
| 51 | buf += str + "\n"; | ||
| 52 | ab = array of byte buf; | ||
| 53 | write(fd, ab, len ab); | ||
| 54 | buf = "dumpdir " + dir + "\n"; | ||
| 55 | ab = array of byte buf; | ||
| 56 | write(fd, ab, len ab); | ||
| 57 | exit; | ||
| 58 | } | ||
| 59 | |||
| 60 | user(): string | ||
| 61 | { | ||
| 62 | fd := open("/dev/user", OREAD); | ||
| 63 | if(fd == nil) | ||
| 64 | return "inferno"; | ||
| 65 | buf := array[Sys->NAMEMAX] of byte; | ||
| 66 | n := read(fd, buf, len buf); | ||
| 67 | if(n <= 0) | ||
| 68 | return "inferno"; | ||
| 69 | return string buf[0:n]; | ||
| 70 | } | ||
| @@ -0,0 +1,22 @@ | |||
| 1 | <../../../../../mkconfig | ||
| 2 | |||
| 3 | TARG=\ | ||
| 4 | win.dis\ | ||
| 5 | winm.dis\ | ||
| 6 | adiff.dis\ | ||
| 7 | agrep.dis\ | ||
| 8 | new.dis\ | ||
| 9 | spout.dis\ | ||
| 10 | awd.dis\ | ||
| 11 | cd.dis\ | ||
| 12 | |||
| 13 | MODULES=\ | ||
| 14 | |||
| 15 | SYSMODULES=\ | ||
| 16 | sh.m\ | ||
| 17 | sys.m\ | ||
| 18 | draw.m\ | ||
| 19 | |||
| 20 | DISBIN=$ROOT/acme/dis | ||
| 21 | |||
| 22 | <$ROOT/mkfiles/mkdis | ||
| @@ -0,0 +1,70 @@ | |||
| 1 | implement New; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "sh.m"; | ||
| 6 | include "workdir.m"; | ||
| 7 | |||
| 8 | New : module { | ||
| 9 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 10 | }; | ||
| 11 | |||
| 12 | sys : Sys; | ||
| 13 | |||
| 14 | init(ctxt : ref Draw->Context, argl : list of string) | ||
| 15 | { | ||
| 16 | sys = load Sys Sys->PATH; | ||
| 17 | workdir := load Workdir Workdir->PATH; | ||
| 18 | if (len argl <= 1) | ||
| 19 | return; | ||
| 20 | ncfd := sys->open("/mnt/acme/new/ctl", Sys->OREAD); | ||
| 21 | if (ncfd == nil) | ||
| 22 | return; | ||
| 23 | b := array[128] of byte; | ||
| 24 | n := sys->read(ncfd, b, len b); | ||
| 25 | id := string int string b[0:n]; | ||
| 26 | buf := "/mnt/acme/" + id + "/ctl"; | ||
| 27 | icfd := sys->open(buf, Sys->OWRITE); | ||
| 28 | if (icfd == nil) | ||
| 29 | return; | ||
| 30 | base := hd tl argl; | ||
| 31 | for (i := len base - 1; i >= 0; --i) | ||
| 32 | if (base[i] == '/') { | ||
| 33 | base = base[i+1:]; | ||
| 34 | break; | ||
| 35 | } | ||
| 36 | buf = "name " + workdir->init() + "/-" + base + "\n"; | ||
| 37 | b = array of byte buf; | ||
| 38 | sys->write(icfd, b, len b); | ||
| 39 | buf = "/mnt/acme/" + id + "/body"; | ||
| 40 | bfd := sys->open(buf, Sys->OWRITE); | ||
| 41 | if (bfd == nil) | ||
| 42 | return; | ||
| 43 | sys->dup(bfd.fd, 1); | ||
| 44 | sys->dup(1, 2); | ||
| 45 | spawn exec(hd tl argl, tl argl, ctxt); | ||
| 46 | b = array of byte "clean\n"; | ||
| 47 | sys->write(icfd, b, len b); | ||
| 48 | } | ||
| 49 | |||
| 50 | exec(cmd : string, argl : list of string, ctxt : ref Draw->Context) | ||
| 51 | { | ||
| 52 | file := cmd; | ||
| 53 | if(len file<4 || file[len file-4:]!=".dis") | ||
| 54 | file += ".dis"; | ||
| 55 | c := load Command file; | ||
| 56 | if(c == nil) { | ||
| 57 | err := sys->sprint("%r"); | ||
| 58 | if(file[0]!='/' && file[0:2]!="./"){ | ||
| 59 | c = load Command "/dis/"+file; | ||
| 60 | if(c == nil) | ||
| 61 | err = sys->sprint("%r"); | ||
| 62 | } | ||
| 63 | if(c == nil){ | ||
| 64 | sys->fprint(sys->fildes(2), "%s: %s\n", cmd, err); | ||
| 65 | return; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | c->init(ctxt, argl); | ||
| 69 | exit; | ||
| 70 | } | ||
| @@ -0,0 +1,143 @@ | |||
| 1 | implement Spout; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | |||
| 7 | Spout : module { | ||
| 8 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 9 | }; | ||
| 10 | |||
| 11 | sys : Sys; | ||
| 12 | bufio : Bufio; | ||
| 13 | |||
| 14 | OREAD, OWRITE, ORDWR, FORKNS, FORKFD, NEWPGRP, MREPL, FD, UTFmax, pctl, open, read, write, fprint, sprint, fildes, bind, dup, byte2char, utfbytes : import sys; | ||
| 15 | Iobuf : import bufio; | ||
| 16 | |||
| 17 | stdin, stdout, stderr : ref FD; | ||
| 18 | |||
| 19 | init(nil : ref Draw->Context, argl : list of string) | ||
| 20 | { | ||
| 21 | sys = load Sys Sys->PATH; | ||
| 22 | bufio = load Bufio Bufio->PATH; | ||
| 23 | stdin = fildes(0); | ||
| 24 | stdout = fildes(1); | ||
| 25 | stderr = fildes(2); | ||
| 26 | main(argl); | ||
| 27 | } | ||
| 28 | |||
| 29 | bout : ref Iobuf; | ||
| 30 | |||
| 31 | main(argv : list of string) | ||
| 32 | { | ||
| 33 | fd : ref FD; | ||
| 34 | |||
| 35 | bout = bufio->fopen(stdout, OWRITE); | ||
| 36 | if(len argv == 1) | ||
| 37 | spout(stdin, ""); | ||
| 38 | else | ||
| 39 | for(argv = tl argv; argv != nil; argv = tl argv){ | ||
| 40 | fd = open(hd argv, OREAD); | ||
| 41 | if(fd == nil){ | ||
| 42 | fprint(stderr, "spell: can't open %s: %r\n", hd argv); | ||
| 43 | continue; | ||
| 44 | } | ||
| 45 | spout(fd, hd argv); | ||
| 46 | fd = nil; | ||
| 47 | } | ||
| 48 | exit; | ||
| 49 | } | ||
| 50 | |||
| 51 | alpha(c : int) : int | ||
| 52 | { | ||
| 53 | return ('a'<=(c) && (c)<='z') || ('A'<=(c) && (c)<='Z'); | ||
| 54 | } | ||
| 55 | |||
| 56 | b : ref Iobuf; | ||
| 57 | |||
| 58 | spout(fd : ref FD, name : string) | ||
| 59 | { | ||
| 60 | s, buf : string; | ||
| 61 | t, w : int; | ||
| 62 | inword, wordchar : int; | ||
| 63 | n, wn, c, m : int; | ||
| 64 | |||
| 65 | b = bufio->fopen(fd, OREAD); | ||
| 66 | n = 0; | ||
| 67 | wn = 0; | ||
| 68 | while((s = b.gets('\n')) != nil){ | ||
| 69 | if(s[len s-1] != '\n') | ||
| 70 | s[len s] = '\n'; | ||
| 71 | if(s[0] == '.') { | ||
| 72 | for(c=0; c<3 && c < len s && s[c]>' '; c++) | ||
| 73 | n++; | ||
| 74 | s = s[c:]; | ||
| 75 | } | ||
| 76 | inword = 0; | ||
| 77 | w = 0; | ||
| 78 | t = 0; | ||
| 79 | do{ | ||
| 80 | c = s[t]; | ||
| 81 | wordchar = 0; | ||
| 82 | if(alpha(c)) | ||
| 83 | wordchar = 1; | ||
| 84 | if(inword && !wordchar){ | ||
| 85 | if(c=='\'' && alpha(s[t+1])) { | ||
| 86 | n++; | ||
| 87 | t++; | ||
| 88 | continue; | ||
| 89 | } | ||
| 90 | m = t-w; | ||
| 91 | if(m > 1){ | ||
| 92 | buf = s[w:w+m]; | ||
| 93 | bout.puts(sprint("%s:#%d,#%d:%s\n", name, wn, n, buf)); | ||
| 94 | } | ||
| 95 | inword = 0; | ||
| 96 | }else if(!inword && wordchar){ | ||
| 97 | wn = n; | ||
| 98 | w = t; | ||
| 99 | inword = 1; | ||
| 100 | } | ||
| 101 | if(c=='\\' && (alpha(s[t+1]) || s[t+1]=='(')){ | ||
| 102 | case(s[t+1]){ | ||
| 103 | '(' => | ||
| 104 | m = 4; | ||
| 105 | break; | ||
| 106 | 'f' => | ||
| 107 | if(s[t+2] == '(') | ||
| 108 | m = 5; | ||
| 109 | else | ||
| 110 | m = 3; | ||
| 111 | break; | ||
| 112 | 's' => | ||
| 113 | if(s[t+2] == '+' || s[t+2]=='-'){ | ||
| 114 | if(s[t+3] == '(') | ||
| 115 | m = 6; | ||
| 116 | else | ||
| 117 | m = 4; | ||
| 118 | }else{ | ||
| 119 | if(s[t+2] == '(') | ||
| 120 | m = 5; | ||
| 121 | else if(s[t+2]=='1' || s[t+2]=='2' || s[t+2]=='3') | ||
| 122 | m = 4; | ||
| 123 | else | ||
| 124 | m = 3; | ||
| 125 | } | ||
| 126 | break; | ||
| 127 | * => | ||
| 128 | m = 2; | ||
| 129 | } | ||
| 130 | while(m-- > 0){ | ||
| 131 | if(s[t] == '\n') | ||
| 132 | break; | ||
| 133 | n++; | ||
| 134 | t++; | ||
| 135 | } | ||
| 136 | continue; | ||
| 137 | } | ||
| 138 | n++; | ||
| 139 | t ++; | ||
| 140 | }while(c != '\n'); | ||
| 141 | } | ||
| 142 | bout.flush(); | ||
| 143 | } | ||
| @@ -0,0 +1,770 @@ | |||
| 1 | implement Win; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "workdir.m"; | ||
| 6 | include "sh.m"; | ||
| 7 | include "env.m"; | ||
| 8 | |||
| 9 | sys : Sys; | ||
| 10 | workdir : Workdir; | ||
| 11 | env: Env; | ||
| 12 | |||
| 13 | OREAD, OWRITE, ORDWR, FORKNS, FORKENV, FORKFD, NEWPGRP, MREPL, FD, UTFmax, pctl, open, read, write, fprint, sprint, fildes, bind, dup, byte2char, utfbytes : import sys; | ||
| 14 | |||
| 15 | Win : module { | ||
| 16 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 17 | }; | ||
| 18 | |||
| 19 | Runeself : con 16r80; | ||
| 20 | |||
| 21 | PNPROC, PNGROUP : con iota; | ||
| 22 | |||
| 23 | stdout, stderr : ref FD; | ||
| 24 | |||
| 25 | drawctxt : ref Draw->Context; | ||
| 26 | finish : chan of int; | ||
| 27 | |||
| 28 | Lock : adt { | ||
| 29 | c : chan of int; | ||
| 30 | |||
| 31 | init : fn() : ref Lock; | ||
| 32 | lock : fn(l : self ref Lock); | ||
| 33 | unlock : fn(l : self ref Lock); | ||
| 34 | }; | ||
| 35 | |||
| 36 | init(ctxt : ref Draw->Context, argl : list of string) | ||
| 37 | { | ||
| 38 | sys = load Sys Sys->PATH; | ||
| 39 | workdir = load Workdir Workdir->PATH; | ||
| 40 | env = load Env Env->PATH; | ||
| 41 | drawctxt = ctxt; | ||
| 42 | stdout = fildes(1); | ||
| 43 | stderr = fildes(2); | ||
| 44 | debuginit(); | ||
| 45 | finish = chan[1] of int; | ||
| 46 | spawn main(argl); | ||
| 47 | <-finish; | ||
| 48 | } | ||
| 49 | |||
| 50 | Lock.init() : ref Lock | ||
| 51 | { | ||
| 52 | return ref Lock(chan[1] of int); | ||
| 53 | } | ||
| 54 | |||
| 55 | Lock.lock(l : self ref Lock) | ||
| 56 | { | ||
| 57 | l.c <-= 1; | ||
| 58 | } | ||
| 59 | |||
| 60 | Lock.unlock(l : self ref Lock) | ||
| 61 | { | ||
| 62 | <-l.c; | ||
| 63 | } | ||
| 64 | |||
| 65 | dlock : ref Lock; | ||
| 66 | debfd : ref Sys->FD; | ||
| 67 | |||
| 68 | debuginit() | ||
| 69 | { | ||
| 70 | # debfd = sys->create("./debugwin", Sys->OWRITE, 8r600); | ||
| 71 | # dlock = Lock.init(); | ||
| 72 | } | ||
| 73 | |||
| 74 | debugpr(nil : string) | ||
| 75 | { | ||
| 76 | # fprint(debfd, "%s", s); | ||
| 77 | } | ||
| 78 | |||
| 79 | debug(nil : string) | ||
| 80 | { | ||
| 81 | # dlock.lock(); | ||
| 82 | # fprint(debfd, "%s", s); | ||
| 83 | # dlock.unlock(); | ||
| 84 | } | ||
| 85 | |||
| 86 | exec(cmd : string, argl : list of string) | ||
| 87 | { | ||
| 88 | file := cmd; | ||
| 89 | if(len file<4 || file[len file-4:]!=".dis") | ||
| 90 | file += ".dis"; | ||
| 91 | |||
| 92 | c := load Command file; | ||
| 93 | if(c == nil) { | ||
| 94 | err := sprint("%r"); | ||
| 95 | if(file[0]!='/' && file[0:2]!="./"){ | ||
| 96 | c = load Command "/dis/"+file; | ||
| 97 | if(c == nil) | ||
| 98 | err = sprint("%r"); | ||
| 99 | } | ||
| 100 | if(c == nil){ | ||
| 101 | fprint(stderr, "%s: %s\n", cmd, err); | ||
| 102 | return; | ||
| 103 | } | ||
| 104 | } | ||
| 105 | c->init(drawctxt, argl); | ||
| 106 | } | ||
| 107 | |||
| 108 | postnote(t : int, pid : int, note : string) : int | ||
| 109 | { | ||
| 110 | # fd := open("/prog/" + string pid + "/ctl", OWRITE); | ||
| 111 | fd := open("#p/" + string pid + "/ctl", OWRITE); | ||
| 112 | if (fd == nil) | ||
| 113 | return -1; | ||
| 114 | if (t == PNGROUP) | ||
| 115 | note += "grp"; | ||
| 116 | fprint(fd, "%s", note); | ||
| 117 | |||
| 118 | fd = nil; | ||
| 119 | return 0; | ||
| 120 | } | ||
| 121 | |||
| 122 | sysname(): string | ||
| 123 | { | ||
| 124 | fd := sys->open("#c/sysname", sys->OREAD); | ||
| 125 | if(fd == nil) | ||
| 126 | return nil; | ||
| 127 | buf := array[128] of byte; | ||
| 128 | n := sys->read(fd, buf, len buf); | ||
| 129 | if(n < 0) | ||
| 130 | return nil; | ||
| 131 | return string buf[0:n]; | ||
| 132 | } | ||
| 133 | |||
| 134 | EVENTSIZE : con 256; | ||
| 135 | |||
| 136 | Event : adt { | ||
| 137 | c1 : int; | ||
| 138 | c2 : int; | ||
| 139 | q0 : int; | ||
| 140 | q1 : int; | ||
| 141 | flag : int; | ||
| 142 | nb : int; | ||
| 143 | nr : int; | ||
| 144 | b : array of byte; | ||
| 145 | r : array of int; | ||
| 146 | }; | ||
| 147 | |||
| 148 | blank : ref Event; | ||
| 149 | |||
| 150 | pid : int; | ||
| 151 | # pgrpfd : ref FD; | ||
| 152 | parentpid : int; | ||
| 153 | |||
| 154 | typing : array of byte; | ||
| 155 | ntypeb : int; | ||
| 156 | ntyper : int; | ||
| 157 | ntypebreak : int; | ||
| 158 | |||
| 159 | Q : adt { | ||
| 160 | l : ref Lock; | ||
| 161 | p : int; | ||
| 162 | k : int; | ||
| 163 | }; | ||
| 164 | |||
| 165 | q : Q; | ||
| 166 | |||
| 167 | newevent(n : int) : ref Event | ||
| 168 | { | ||
| 169 | e := ref Event; | ||
| 170 | e.b = array[n*UTFmax+1] of byte; | ||
| 171 | e.r = array[n+1] of int; | ||
| 172 | return e; | ||
| 173 | } | ||
| 174 | |||
| 175 | main(argv : list of string) | ||
| 176 | { | ||
| 177 | program : list of string; | ||
| 178 | fd, ctlfd, eventfd, addrfd, datafd : ref FD; | ||
| 179 | id : int; | ||
| 180 | c : chan of int; | ||
| 181 | name : string; | ||
| 182 | |||
| 183 | sys->pctl(Sys->NEWPGRP, nil); | ||
| 184 | q.l = Lock.init(); | ||
| 185 | blank = newevent(2); | ||
| 186 | blank.c1 = 'M'; | ||
| 187 | blank.c2 = 'X'; | ||
| 188 | blank.q0 = blank.q1 = blank.flag = 0; | ||
| 189 | blank.nb = blank.nr = 1; | ||
| 190 | blank.b[0] = byte ' '; | ||
| 191 | blank.b[1] = byte 0; | ||
| 192 | blank.r[0] = ' '; | ||
| 193 | blank.r[1] = 0; | ||
| 194 | pctl(FORKNS|NEWPGRP, nil); | ||
| 195 | parentpid = pctl(0, nil); | ||
| 196 | program = nil; | ||
| 197 | if(tl argv != nil) | ||
| 198 | program = tl argv; | ||
| 199 | name = nil; | ||
| 200 | if(program == nil){ | ||
| 201 | # program = "-i" :: program; | ||
| 202 | program = "sh" :: program; | ||
| 203 | name = sysname(); | ||
| 204 | } | ||
| 205 | if(name == nil){ | ||
| 206 | prog := hd program; | ||
| 207 | for (n := len prog - 1; n >= 0; n--) | ||
| 208 | if (prog[n] == '/') | ||
| 209 | break; | ||
| 210 | if(n >= 0) | ||
| 211 | name = prog[n+1:]; | ||
| 212 | else | ||
| 213 | name = prog; | ||
| 214 | argl := tl argv; | ||
| 215 | if (argl != nil) { | ||
| 216 | for(argl = tl argl; argl != nil && len(name)+1+len(hd argl)<16; argl = tl argl) | ||
| 217 | name += "_" + hd argl; | ||
| 218 | } | ||
| 219 | } | ||
| 220 | if(bind("#|", "/dev/acme", MREPL) < 0) | ||
| 221 | error("pipe"); | ||
| 222 | ctlfd = open("/chan/new/ctl", ORDWR); | ||
| 223 | buf := array[12] of byte; | ||
| 224 | if(ctlfd==nil || read(ctlfd, buf, 12)!=12) | ||
| 225 | error("ctl"); | ||
| 226 | id = int string buf; | ||
| 227 | buf = nil; | ||
| 228 | env->setenv("acmewin", string id); | ||
| 229 | b := sprint("/chan/%d/tag", id); | ||
| 230 | fd = open(b, OWRITE); | ||
| 231 | write(fd, array of byte " Send Delete", 12); | ||
| 232 | fd = nil; | ||
| 233 | b = sprint("/chan/%d/event", id); | ||
| 234 | eventfd = open(b, ORDWR); | ||
| 235 | b = sprint("/chan/%d/addr", id); | ||
| 236 | addrfd = open(b, ORDWR); | ||
| 237 | b = sprint("/chan/%d/data", id); | ||
| 238 | datafd = open(b, ORDWR); # OCEXEC | ||
| 239 | if(eventfd==nil || addrfd==nil || datafd==nil) | ||
| 240 | error("data files"); | ||
| 241 | c = chan of int; | ||
| 242 | spawn run(program, id, c); | ||
| 243 | pid = <-c; | ||
| 244 | # b = sprint("/prog/%d/notepg", pid); | ||
| 245 | # pgrpfd = open(b, OWRITE); # OCEXEC | ||
| 246 | # if(pgrpfd == nil) | ||
| 247 | # fprint(stdout, "warning: win can't open notepg: %r\n"); | ||
| 248 | c <-= 1; | ||
| 249 | fd = open("/dev/acme/data", ORDWR); | ||
| 250 | if(fd == nil) | ||
| 251 | error("/dev/acme/data"); | ||
| 252 | wd := workdir->init(); | ||
| 253 | # b = sprint("name %s/-%s\n0\n", wd, name); | ||
| 254 | b = sprint("name %s/-%s\n", wd, name); | ||
| 255 | ab := array of byte b; | ||
| 256 | write(ctlfd, ab, len ab); | ||
| 257 | b = sprint("dumpdir %s/\n", wd); | ||
| 258 | ab = array of byte b; | ||
| 259 | write(ctlfd, ab, len ab); | ||
| 260 | b = sprint("dump %s\n", onestring(argv)); | ||
| 261 | ab = array of byte b; | ||
| 262 | write(ctlfd, ab, len ab); | ||
| 263 | ab = nil; | ||
| 264 | spawn stdinx(fd, ctlfd, eventfd, addrfd, datafd); | ||
| 265 | stdoutx(fd, addrfd, datafd); | ||
| 266 | } | ||
| 267 | |||
| 268 | run(argv : list of string, id : int, c : chan of int) | ||
| 269 | { | ||
| 270 | fd0, fd1 : ref FD; | ||
| 271 | |||
| 272 | pctl(FORKENV|FORKFD|NEWPGRP, nil); # had RFMEM | ||
| 273 | c <-= pctl(0, nil); | ||
| 274 | <-c; | ||
| 275 | pctl(FORKNS, nil); | ||
| 276 | if(bind("/dev/acme/data1", "/dev/cons", MREPL) < 0){ | ||
| 277 | fprint(stderr, "can't bind /dev/cons: %r\n"); | ||
| 278 | exit; | ||
| 279 | } | ||
| 280 | fd0 = open("/dev/cons", OREAD); | ||
| 281 | fd1 = open("/dev/cons", OWRITE); | ||
| 282 | if(fd0==nil || fd1==nil){ | ||
| 283 | fprint(stderr, "can't open /dev/cons: %r\n"); | ||
| 284 | exit; | ||
| 285 | } | ||
| 286 | dup(fd0.fd, 0); | ||
| 287 | dup(fd1.fd, 1); | ||
| 288 | dup(fd1.fd, 2); | ||
| 289 | fd0 = fd1 = nil; | ||
| 290 | b := sprint("/chan/%d", id); | ||
| 291 | if(bind(b, "/dev/acme", MREPL) < 0) | ||
| 292 | error("bind /dev/acme"); | ||
| 293 | if(bind(sprint("/chan/%d/consctl", id), "/dev/consctl", MREPL) < 0) | ||
| 294 | error("bind /dev/consctl"); | ||
| 295 | exec(hd argv, argv); | ||
| 296 | exit; | ||
| 297 | } | ||
| 298 | |||
| 299 | killing : int = 0; | ||
| 300 | |||
| 301 | error(s : string) | ||
| 302 | { | ||
| 303 | if(s != nil) | ||
| 304 | fprint(stderr, "win: %s: %r\n", s); | ||
| 305 | if (killing) | ||
| 306 | return; | ||
| 307 | killing = 1; | ||
| 308 | s = "kill"; | ||
| 309 | if(pid) | ||
| 310 | postnote(PNGROUP, pid, s); | ||
| 311 | # write(pgrpfd, array of byte "hangup", 6); | ||
| 312 | postnote(PNGROUP, parentpid, s); | ||
| 313 | finish <-= 1; | ||
| 314 | exit; | ||
| 315 | } | ||
| 316 | |||
| 317 | buff := array[8192] of byte; | ||
| 318 | bufp : int; | ||
| 319 | nbuf : int; | ||
| 320 | |||
| 321 | onestring(argv : list of string) : string | ||
| 322 | { | ||
| 323 | s : string; | ||
| 324 | |||
| 325 | if(argv == nil) | ||
| 326 | return ""; | ||
| 327 | for( ; argv != nil; argv = tl argv){ | ||
| 328 | s += hd argv; | ||
| 329 | if (tl argv != nil) | ||
| 330 | s += " "; | ||
| 331 | } | ||
| 332 | return s; | ||
| 333 | } | ||
| 334 | |||
| 335 | getec(efd : ref FD) : int | ||
| 336 | { | ||
| 337 | if(nbuf == 0){ | ||
| 338 | nbuf = read(efd, buff, len buff); | ||
| 339 | if(nbuf <= 0) | ||
| 340 | error(nil); | ||
| 341 | bufp = 0; | ||
| 342 | } | ||
| 343 | --nbuf; | ||
| 344 | return int buff[bufp++]; | ||
| 345 | } | ||
| 346 | |||
| 347 | geten(efd : ref FD) : int | ||
| 348 | { | ||
| 349 | n, c : int; | ||
| 350 | |||
| 351 | n = 0; | ||
| 352 | while('0'<=(c=getec(efd)) && c<='9') | ||
| 353 | n = n*10+(c-'0'); | ||
| 354 | if(c != ' ') | ||
| 355 | error("event number syntax"); | ||
| 356 | return n; | ||
| 357 | } | ||
| 358 | |||
| 359 | geter(efd : ref FD, buf : array of byte) : (int, int) | ||
| 360 | { | ||
| 361 | r, m, n, ok : int; | ||
| 362 | |||
| 363 | r = getec(efd); | ||
| 364 | buf[0] = byte r; | ||
| 365 | n = 1; | ||
| 366 | if(r < Runeself) | ||
| 367 | return (r, n); | ||
| 368 | for (;;) { | ||
| 369 | (r, m, ok) = byte2char(buf[0:n], 0); | ||
| 370 | if (m > 0) | ||
| 371 | return (r, n); | ||
| 372 | buf[n++] = byte getec(efd); | ||
| 373 | } | ||
| 374 | return (0, 0); | ||
| 375 | } | ||
| 376 | |||
| 377 | gete(efd : ref FD, e : ref Event) | ||
| 378 | { | ||
| 379 | i, nb : int; | ||
| 380 | |||
| 381 | e.c1 = getec(efd); | ||
| 382 | e.c2 = getec(efd); | ||
| 383 | e.q0 = geten(efd); | ||
| 384 | e.q1 = geten(efd); | ||
| 385 | e.flag = geten(efd); | ||
| 386 | e.nr = geten(efd); | ||
| 387 | if(e.nr > EVENTSIZE) | ||
| 388 | error("event string too long"); | ||
| 389 | e.nb = 0; | ||
| 390 | for(i=0; i<e.nr; i++){ | ||
| 391 | (e.r[i], nb) = geter(efd, e.b[e.nb:]); | ||
| 392 | e.nb += nb; | ||
| 393 | } | ||
| 394 | e.r[e.nr] = 0; | ||
| 395 | e.b[e.nb] = byte 0; | ||
| 396 | if(getec(efd) != '\n') | ||
| 397 | error("event syntax 2"); | ||
| 398 | } | ||
| 399 | |||
| 400 | nrunes(s : array of byte, nb : int) : int | ||
| 401 | { | ||
| 402 | i, n, r, b, ok : int; | ||
| 403 | |||
| 404 | n = 0; | ||
| 405 | for(i=0; i<nb; n++) { | ||
| 406 | (r, b, ok) = byte2char(s, i); | ||
| 407 | if (b == 0) | ||
| 408 | error("not full string in nrunes()"); | ||
| 409 | i += b; | ||
| 410 | } | ||
| 411 | return n; | ||
| 412 | } | ||
| 413 | |||
| 414 | stdinx(fd0 : ref FD, cfd : ref FD, efd : ref FD, afd : ref FD, dfd : ref FD) | ||
| 415 | { | ||
| 416 | e, e2, e3, e4 : ref Event; | ||
| 417 | |||
| 418 | e = newevent(EVENTSIZE); | ||
| 419 | e2 = newevent(EVENTSIZE); | ||
| 420 | e3 = newevent(EVENTSIZE); | ||
| 421 | e4 = newevent(EVENTSIZE); | ||
| 422 | for(;;){ | ||
| 423 | gete(efd, e); | ||
| 424 | q.l.lock(); | ||
| 425 | case(e.c1){ | ||
| 426 | 'E' => # write to body; can't affect us | ||
| 427 | break; | ||
| 428 | 'F' => # generated by our actions; ignore | ||
| 429 | break; | ||
| 430 | 'K' or 'M' => | ||
| 431 | case(e.c2){ | ||
| 432 | 'R' => | ||
| 433 | addtype(' ', ntyper, e.b, e.nb, e.nr); | ||
| 434 | sendtype(fd0, 1); | ||
| 435 | break; | ||
| 436 | 'I' => | ||
| 437 | if(e.q0 < q.p) | ||
| 438 | q.p += e.q1-e.q0; | ||
| 439 | else if(e.q0 <= q.p+ntyper) | ||
| 440 | typex(e, fd0, afd, dfd); | ||
| 441 | break; | ||
| 442 | 'D' => | ||
| 443 | q.p -= delete(e); | ||
| 444 | break; | ||
| 445 | 'x' or 'X' => | ||
| 446 | if(e.flag & 2) | ||
| 447 | gete(efd, e2); | ||
| 448 | if(e.flag & 8){ | ||
| 449 | gete(efd, e3); | ||
| 450 | gete(efd, e4); | ||
| 451 | } | ||
| 452 | if(e.flag&1 || (e.c2=='x' && e.nr==0 && e2.nr==0)){ | ||
| 453 | # send it straight back | ||
| 454 | fprint(efd, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1); | ||
| 455 | break; | ||
| 456 | } | ||
| 457 | if(e.q0==e.q1 && (e.flag&2)){ | ||
| 458 | e2.flag = e.flag; | ||
| 459 | *e = *e2; | ||
| 460 | } | ||
| 461 | if(e.flag & 8){ | ||
| 462 | if(e.q1 != e.q0){ | ||
| 463 | send(e, fd0, cfd, afd, dfd, 0); | ||
| 464 | send(blank, fd0, cfd, afd, dfd, 0); | ||
| 465 | } | ||
| 466 | send(e3, fd0, cfd, afd, dfd, 1); | ||
| 467 | }else if(e.q1 != e.q0) | ||
| 468 | send(e, fd0, cfd, afd, dfd, 1); | ||
| 469 | break; | ||
| 470 | 'l' or 'L' => | ||
| 471 | # just send it back | ||
| 472 | if(e.flag & 2) | ||
| 473 | gete(efd, e2); | ||
| 474 | fprint(efd, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1); | ||
| 475 | break; | ||
| 476 | 'd' or 'i' => | ||
| 477 | break; | ||
| 478 | * => | ||
| 479 | fprint(stdout, "unknown message %c%c\n", e.c1, e.c2); | ||
| 480 | break; | ||
| 481 | } | ||
| 482 | * => | ||
| 483 | fprint(stdout, "unknown message %c%c\n", e.c1, e.c2); | ||
| 484 | break; | ||
| 485 | } | ||
| 486 | q.l.unlock(); | ||
| 487 | } | ||
| 488 | } | ||
| 489 | |||
| 490 | stdoutx(fd1 : ref FD, afd : ref FD, dfd : ref FD) | ||
| 491 | { | ||
| 492 | n, m, w, npart : int; | ||
| 493 | s, t : int; | ||
| 494 | buf, hold, x : array of byte; | ||
| 495 | r, ok : int; | ||
| 496 | |||
| 497 | buf = array[8192+UTFmax+1] of byte; | ||
| 498 | hold = array[UTFmax] of byte; | ||
| 499 | npart = 0; | ||
| 500 | for(;;){ | ||
| 501 | n = read(fd1, buf[npart:], 8192); | ||
| 502 | if(n < 0) | ||
| 503 | error(nil); | ||
| 504 | if(n == 0) | ||
| 505 | continue; | ||
| 506 | |||
| 507 | # squash NULs | ||
| 508 | for (s = 0; s < n; s++) | ||
| 509 | if (buf[npart+s] == byte 0) | ||
| 510 | break; | ||
| 511 | if(s < n){ | ||
| 512 | for(t=s; s<n; s++) | ||
| 513 | if(buf[npart+t] == buf[npart+s]) # assign = | ||
| 514 | t++; | ||
| 515 | n = t; | ||
| 516 | } | ||
| 517 | |||
| 518 | n += npart; | ||
| 519 | |||
| 520 | # hold on to final partial rune | ||
| 521 | npart = 0; | ||
| 522 | while(n>0 && (int buf[n-1]&16rC0)){ | ||
| 523 | --n; | ||
| 524 | npart++; | ||
| 525 | if((int buf[n]&16rC0)!=16r80){ | ||
| 526 | if(utfbytes(buf[n:], npart) > 0){ | ||
| 527 | (r, w, ok) = byte2char(buf, n); | ||
| 528 | n += w; | ||
| 529 | npart -= w; | ||
| 530 | } | ||
| 531 | break; | ||
| 532 | } | ||
| 533 | } | ||
| 534 | if(n > 0){ | ||
| 535 | hold[0:] = buf[n:n+npart]; | ||
| 536 | buf[n] = byte 0; | ||
| 537 | q.l.lock(); | ||
| 538 | str := sprint("#%d", q.p); | ||
| 539 | x = array of byte str; | ||
| 540 | m = len x; | ||
| 541 | if(write(afd, x, m) != m) | ||
| 542 | error("stdout writing address"); | ||
| 543 | x = nil; | ||
| 544 | if(write(dfd, buf, n) != n) | ||
| 545 | error("stdout writing body"); | ||
| 546 | q.p += nrunes(buf, n); | ||
| 547 | q.l.unlock(); | ||
| 548 | buf[0:] = hold[0:npart]; | ||
| 549 | } | ||
| 550 | } | ||
| 551 | } | ||
| 552 | |||
| 553 | delete(e : ref Event) : int | ||
| 554 | { | ||
| 555 | q0, q1 : int; | ||
| 556 | deltap : int; | ||
| 557 | |||
| 558 | q0 = e.q0; | ||
| 559 | q1 = e.q1; | ||
| 560 | if(q1 <= q.p) | ||
| 561 | return e.q1-e.q0; | ||
| 562 | if(q0 >= q.p+ntyper) | ||
| 563 | return 0; | ||
| 564 | deltap = 0; | ||
| 565 | if(q0 < q.p){ | ||
| 566 | deltap = q.p-q0; | ||
| 567 | q0 = 0; | ||
| 568 | }else | ||
| 569 | q0 -= q.p; | ||
| 570 | if(q1 > q.p+ntyper) | ||
| 571 | q1 = ntyper; | ||
| 572 | else | ||
| 573 | q1 -= q.p; | ||
| 574 | deltype(q0, q1); | ||
| 575 | return deltap; | ||
| 576 | } | ||
| 577 | |||
| 578 | addtype(c : int, p0 : int, b : array of byte, nb : int, nr : int) | ||
| 579 | { | ||
| 580 | i, w : int; | ||
| 581 | r, ok : int; | ||
| 582 | p : int; | ||
| 583 | b0 : int; | ||
| 584 | |||
| 585 | for(i=0; i<nb; i+=w){ | ||
| 586 | (r, w, ok) = byte2char(b, i); | ||
| 587 | if(r==16r7F && c=='K'){ | ||
| 588 | if (pid) | ||
| 589 | postnote(PNGROUP, pid, "kill"); | ||
| 590 | # write(pgrpfd, array of byte "interrupt", 9); | ||
| 591 | # toss all typing | ||
| 592 | q.p += ntyper+nr; | ||
| 593 | ntypebreak = 0; | ||
| 594 | ntypeb = 0; | ||
| 595 | ntyper = 0; | ||
| 596 | # buglet: more than one delete ignored | ||
| 597 | return; | ||
| 598 | } | ||
| 599 | if(r=='\n' || r==16r04) | ||
| 600 | ntypebreak++; | ||
| 601 | } | ||
| 602 | ot := typing; | ||
| 603 | typing = array[ntypeb+nb] of byte; | ||
| 604 | if(typing == nil) | ||
| 605 | error("realloc"); | ||
| 606 | if (ot != nil) | ||
| 607 | typing[0:] = ot[0:ntypeb]; | ||
| 608 | ot = nil; | ||
| 609 | if(p0 == ntyper) | ||
| 610 | typing[ntypeb:] = b[0:nb]; | ||
| 611 | else{ | ||
| 612 | b0 = 0; | ||
| 613 | for(p=0; p<p0 && b0<ntypeb; p++){ | ||
| 614 | (r, w, ok) = byte2char(typing[b0:], i); | ||
| 615 | b0 += w; | ||
| 616 | } | ||
| 617 | if(p != p0) | ||
| 618 | error("typing: findrune"); | ||
| 619 | typing[b0+nb:] = typing[b0:ntypeb]; | ||
| 620 | typing[b0:] = b[0:nb]; | ||
| 621 | } | ||
| 622 | ntypeb += nb; | ||
| 623 | ntyper += nr; | ||
| 624 | } | ||
| 625 | |||
| 626 | sendtype(fd0 : ref FD, raw : int) | ||
| 627 | { | ||
| 628 | while(ntypebreak){ | ||
| 629 | brkc := 0; | ||
| 630 | i := 0; | ||
| 631 | while(i<ntypeb){ | ||
| 632 | if(typing[i]==byte '\n' || typing[i]==byte 16r04){ | ||
| 633 | n := i + (typing[i] == byte '\n'); | ||
| 634 | i++; | ||
| 635 | if(write(fd0, typing, n) != n) | ||
| 636 | error("sending to program"); | ||
| 637 | nr := nrunes(typing, i); | ||
| 638 | if (!raw) | ||
| 639 | q.p += nr; | ||
| 640 | ntyper -= nr; | ||
| 641 | ntypeb -= i; | ||
| 642 | typing[0:] = typing[i:i+ntypeb]; | ||
| 643 | i = 0; | ||
| 644 | ntypebreak--; | ||
| 645 | brkc = 1; | ||
| 646 | }else | ||
| 647 | i++; | ||
| 648 | } | ||
| 649 | if (!brkc) { | ||
| 650 | fprint(stdout, "no breakchar\n"); | ||
| 651 | ntypebreak = 0; | ||
| 652 | } | ||
| 653 | } | ||
| 654 | } | ||
| 655 | |||
| 656 | deltype(p0 : int, p1 : int) | ||
| 657 | { | ||
| 658 | w : int; | ||
| 659 | p, b0, b1 : int; | ||
| 660 | r, ok : int; | ||
| 661 | |||
| 662 | # advance to p0 | ||
| 663 | b0 = 0; | ||
| 664 | for(p=0; p<p0 && b0<ntypeb; p++){ | ||
| 665 | (r, w, ok) = byte2char(typing, b0); | ||
| 666 | b0 += w; | ||
| 667 | } | ||
| 668 | if(p != p0) | ||
| 669 | error("deltype 1"); | ||
| 670 | # advance to p1 | ||
| 671 | b1 = b0; | ||
| 672 | for(; p<p1 && b1<ntypeb; p++){ | ||
| 673 | (r, w, ok) = byte2char(typing, b1); | ||
| 674 | b1 += w; | ||
| 675 | if(r=='\n' || r==16r04) | ||
| 676 | ntypebreak--; | ||
| 677 | } | ||
| 678 | if(p != p1) | ||
| 679 | error("deltype 2"); | ||
| 680 | typing[b0:] = typing[b1:ntypeb]; | ||
| 681 | ntypeb -= b1-b0; | ||
| 682 | ntyper -= p1-p0; | ||
| 683 | } | ||
| 684 | |||
| 685 | typex(e : ref Event, fd0 : ref FD, afd : ref FD, dfd : ref FD) | ||
| 686 | { | ||
| 687 | m, n, nr : int; | ||
| 688 | buf : array of byte; | ||
| 689 | |||
| 690 | if(e.nr > 0) | ||
| 691 | addtype(e.c1, e.q0-q.p, e.b, e.nb, e.nr); | ||
| 692 | else{ | ||
| 693 | buf = array[128] of byte; | ||
| 694 | m = e.q0; | ||
| 695 | while(m < e.q1){ | ||
| 696 | str := sprint("#%d", m); | ||
| 697 | b := array of byte str; | ||
| 698 | n = len b; | ||
| 699 | write(afd, b, n); | ||
| 700 | b = nil; | ||
| 701 | n = read(dfd, buf, len buf); | ||
| 702 | nr = nrunes(buf, n); | ||
| 703 | while(m+nr > e.q1){ | ||
| 704 | do; while(n>0 && (int buf[--n]&16rC0)==16r80); | ||
| 705 | --nr; | ||
| 706 | } | ||
| 707 | if(n == 0) | ||
| 708 | break; | ||
| 709 | addtype(e.c1, m-q.p, buf, n, nr); | ||
| 710 | m += nr; | ||
| 711 | } | ||
| 712 | } | ||
| 713 | buf = nil; | ||
| 714 | sendtype(fd0, 0); | ||
| 715 | } | ||
| 716 | |||
| 717 | send(e : ref Event, fd0 : ref FD, cfd : ref FD, afd : ref FD, dfd : ref FD, donl : int) | ||
| 718 | { | ||
| 719 | l, m, n, nr, lastc, end : int; | ||
| 720 | abuf, buf : array of byte; | ||
| 721 | |||
| 722 | buf = array[128] of byte; | ||
| 723 | end = q.p+ntyper; | ||
| 724 | str := sprint("#%d", end); | ||
| 725 | abuf = array of byte str; | ||
| 726 | l = len abuf; | ||
| 727 | write(afd, abuf, l); | ||
| 728 | abuf = nil; | ||
| 729 | if(e.nr > 0){ | ||
| 730 | write(dfd, e.b, e.nb); | ||
| 731 | addtype(e.c1, ntyper, e.b, e.nb, e.nr); | ||
| 732 | lastc = e.r[e.nr-1]; | ||
| 733 | }else{ | ||
| 734 | m = e.q0; | ||
| 735 | lastc = 0; | ||
| 736 | while(m < e.q1){ | ||
| 737 | str = sprint("#%d", m); | ||
| 738 | abuf = array of byte str; | ||
| 739 | n = len abuf; | ||
| 740 | write(afd, abuf, n); | ||
| 741 | abuf = nil; | ||
| 742 | n = read(dfd, buf, len buf); | ||
| 743 | nr = nrunes(buf, n); | ||
| 744 | while(m+nr > e.q1){ | ||
| 745 | do; while(n>0 && (int buf[--n]&16rC0)==16r80); | ||
| 746 | --nr; | ||
| 747 | } | ||
| 748 | if(n == 0) | ||
| 749 | break; | ||
| 750 | str = sprint("#%d", end); | ||
| 751 | abuf = array of byte str; | ||
| 752 | l = len abuf; | ||
| 753 | write(afd, abuf, l); | ||
| 754 | abuf = nil; | ||
| 755 | write(dfd, buf, n); | ||
| 756 | addtype(e.c1, ntyper, buf, n, nr); | ||
| 757 | lastc = int buf[n-1]; | ||
| 758 | m += nr; | ||
| 759 | end += nr; | ||
| 760 | } | ||
| 761 | } | ||
| 762 | if(donl && lastc!='\n'){ | ||
| 763 | write(dfd, array of byte "\n", 1); | ||
| 764 | addtype(e.c1, ntyper, array of byte "\n", 1, 1); | ||
| 765 | } | ||
| 766 | write(cfd, array of byte "dot=addr", 8); | ||
| 767 | sendtype(fd0, 0); | ||
| 768 | buf = nil; | ||
| 769 | } | ||
| 770 | |||
| @@ -0,0 +1,791 @@ | |||
| 1 | implement Win; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "workdir.m"; | ||
| 6 | include "sh.m"; | ||
| 7 | |||
| 8 | sys : Sys; | ||
| 9 | workdir : Workdir; | ||
| 10 | |||
| 11 | OREAD, OWRITE, ORDWR, FORKNS, FORKENV, FORKFD, NEWPGRP, MREPL, FD, UTFmax, pctl, open, read, write, fprint, sprint, fildes, bind, dup, byte2char, utfbytes : import sys; | ||
| 12 | |||
| 13 | Win : module { | ||
| 14 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 15 | }; | ||
| 16 | |||
| 17 | Runeself : con 16r80; | ||
| 18 | |||
| 19 | PNPROC, PNGROUP : con iota; | ||
| 20 | |||
| 21 | stdout, stderr : ref FD; | ||
| 22 | |||
| 23 | drawctxt : ref Draw->Context; | ||
| 24 | |||
| 25 | Lock : adt { | ||
| 26 | cnt : int; | ||
| 27 | chann : chan of int; | ||
| 28 | |||
| 29 | init : fn() : ref Lock; | ||
| 30 | lock : fn(l : self ref Lock); | ||
| 31 | unlock : fn(l : self ref Lock); | ||
| 32 | }; | ||
| 33 | |||
| 34 | lc, uc : chan of ref Lock; | ||
| 35 | lockpid : int; | ||
| 36 | |||
| 37 | init(ctxt : ref Draw->Context, argl : list of string) | ||
| 38 | { | ||
| 39 | sys = load Sys Sys->PATH; | ||
| 40 | workdir = load Workdir Workdir->PATH; | ||
| 41 | drawctxt = ctxt; | ||
| 42 | stdout = fildes(1); | ||
| 43 | stderr = fildes(2); | ||
| 44 | lc = chan of ref Lock; | ||
| 45 | uc = chan of ref Lock; | ||
| 46 | spawn lockmgr(); | ||
| 47 | debuginit(); | ||
| 48 | main(argl); | ||
| 49 | } | ||
| 50 | |||
| 51 | lockmgr() | ||
| 52 | { | ||
| 53 | l : ref Lock; | ||
| 54 | |||
| 55 | lockpid = pctl(0, nil); | ||
| 56 | for (;;) { | ||
| 57 | alt { | ||
| 58 | l = <- lc => | ||
| 59 | if (l.cnt++ == 0) | ||
| 60 | l.chann <-= 1; | ||
| 61 | l = <- uc => | ||
| 62 | if (--l.cnt > 0) | ||
| 63 | l.chann <-= 1; | ||
| 64 | } | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | Lock.init() : ref Lock | ||
| 69 | { | ||
| 70 | return ref Lock(0, chan of int); | ||
| 71 | } | ||
| 72 | |||
| 73 | Lock.lock(l : self ref Lock) | ||
| 74 | { | ||
| 75 | lc <-= l; | ||
| 76 | <- l.chann; | ||
| 77 | } | ||
| 78 | |||
| 79 | Lock.unlock(l : self ref Lock) | ||
| 80 | { | ||
| 81 | uc <-= l; | ||
| 82 | } | ||
| 83 | |||
| 84 | dlock : ref Lock; | ||
| 85 | debfd : ref Sys->FD; | ||
| 86 | |||
| 87 | debuginit() | ||
| 88 | { | ||
| 89 | # debfd = sys->create("./debugwin", Sys->OWRITE, 8r600); | ||
| 90 | # dlock = Lock.init(); | ||
| 91 | } | ||
| 92 | |||
| 93 | debugpr(nil : string) | ||
| 94 | { | ||
| 95 | # fprint(debfd, "%s", s); | ||
| 96 | } | ||
| 97 | |||
| 98 | debug(nil : string) | ||
| 99 | { | ||
| 100 | # dlock.lock(); | ||
| 101 | # fprint(debfd, "%s", s); | ||
| 102 | # dlock.unlock(); | ||
| 103 | } | ||
| 104 | |||
| 105 | exec(cmd : string, argl : list of string) | ||
| 106 | { | ||
| 107 | file := cmd; | ||
| 108 | if(len file<4 || file[len file-4:]!=".dis") | ||
| 109 | file += ".dis"; | ||
| 110 | |||
| 111 | c := load Command file; | ||
| 112 | if(c == nil) { | ||
| 113 | err := sprint("%r"); | ||
| 114 | if(file[0]!='/' && file[0:2]!="./"){ | ||
| 115 | c = load Command "/dis/"+file; | ||
| 116 | if(c == nil) | ||
| 117 | err = sprint("%r"); | ||
| 118 | } | ||
| 119 | if(c == nil){ | ||
| 120 | fprint(stderr, "%s: %s\n", cmd, err); | ||
| 121 | return; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | c->init(drawctxt, argl); | ||
| 125 | } | ||
| 126 | |||
| 127 | postnote(t : int, pid : int, note : string) : int | ||
| 128 | { | ||
| 129 | # fd := open("/prog/" + string pid + "/ctl", OWRITE); | ||
| 130 | fd := open("#p/" + string pid + "/ctl", OWRITE); | ||
| 131 | if (fd == nil) | ||
| 132 | return -1; | ||
| 133 | if (t == PNGROUP) | ||
| 134 | note += "grp"; | ||
| 135 | fprint(fd, "%s", note); | ||
| 136 | |||
| 137 | fd = nil; | ||
| 138 | return 0; | ||
| 139 | } | ||
| 140 | |||
| 141 | sysname(): string | ||
| 142 | { | ||
| 143 | fd := sys->open("#c/sysname", sys->OREAD); | ||
| 144 | if(fd == nil) | ||
| 145 | return nil; | ||
| 146 | buf := array[128] of byte; | ||
| 147 | n := sys->read(fd, buf, len buf); | ||
| 148 | if(n < 0) | ||
| 149 | return nil; | ||
| 150 | return string buf[0:n]; | ||
| 151 | } | ||
| 152 | |||
| 153 | EVENTSIZE : con 256; | ||
| 154 | |||
| 155 | Event : adt { | ||
| 156 | c1 : int; | ||
| 157 | c2 : int; | ||
| 158 | q0 : int; | ||
| 159 | q1 : int; | ||
| 160 | flag : int; | ||
| 161 | nb : int; | ||
| 162 | nr : int; | ||
| 163 | b : array of byte; | ||
| 164 | r : array of int; | ||
| 165 | }; | ||
| 166 | |||
| 167 | blank : ref Event; | ||
| 168 | |||
| 169 | pid : int; | ||
| 170 | # pgrpfd : ref FD; | ||
| 171 | parentpid : int; | ||
| 172 | |||
| 173 | typing : array of byte; | ||
| 174 | ntypeb : int; | ||
| 175 | ntyper : int; | ||
| 176 | ntypebreak : int; | ||
| 177 | |||
| 178 | Q : adt { | ||
| 179 | l : ref Lock; | ||
| 180 | p : int; | ||
| 181 | k : int; | ||
| 182 | }; | ||
| 183 | |||
| 184 | q : Q; | ||
| 185 | |||
| 186 | newevent(n : int) : ref Event | ||
| 187 | { | ||
| 188 | e := ref Event; | ||
| 189 | e.b = array[n*UTFmax+1] of byte; | ||
| 190 | e.r = array[n+1] of int; | ||
| 191 | return e; | ||
| 192 | } | ||
| 193 | |||
| 194 | main(argv : list of string) | ||
| 195 | { | ||
| 196 | spawn main1(argv); | ||
| 197 | exit; | ||
| 198 | } | ||
| 199 | |||
| 200 | main1(argv : list of string) | ||
| 201 | { | ||
| 202 | program : list of string; | ||
| 203 | fd, ctlfd, eventfd, addrfd, datafd : ref FD; | ||
| 204 | id : int; | ||
| 205 | c : chan of int; | ||
| 206 | name : string; | ||
| 207 | |||
| 208 | q.l = Lock.init(); | ||
| 209 | blank = newevent(2); | ||
| 210 | blank.c1 = 'M'; | ||
| 211 | blank.c2 = 'X'; | ||
| 212 | blank.q0 = blank.q1 = blank.flag = 0; | ||
| 213 | blank.nb = blank.nr = 1; | ||
| 214 | blank.b[0] = byte ' '; | ||
| 215 | blank.b[1] = byte 0; | ||
| 216 | blank.r[0] = ' '; | ||
| 217 | blank.r[1] = 0; | ||
| 218 | pctl(FORKNS|NEWPGRP, nil); | ||
| 219 | parentpid = pctl(0, nil); | ||
| 220 | program = nil; | ||
| 221 | if(tl argv != nil) | ||
| 222 | program = tl argv; | ||
| 223 | name = nil; | ||
| 224 | if(program == nil){ | ||
| 225 | # program = "-i" :: program; | ||
| 226 | program = "sh" :: program; | ||
| 227 | name = sysname(); | ||
| 228 | } | ||
| 229 | if(name == nil){ | ||
| 230 | prog := hd program; | ||
| 231 | for (n := len prog - 1; n >= 0; n--) | ||
| 232 | if (prog[n] == '/') | ||
| 233 | break; | ||
| 234 | if(n >= 0) | ||
| 235 | name = prog[n+1:]; | ||
| 236 | else | ||
| 237 | name = prog; | ||
| 238 | argl := tl argv; | ||
| 239 | if (argl != nil) { | ||
| 240 | for(argl = tl argl; argl != nil && len(name)+1+len(hd argl)<16; argl = tl argl) | ||
| 241 | name += "_" + hd argl; | ||
| 242 | } | ||
| 243 | } | ||
| 244 | if(bind("#|", "/dev/acme", MREPL) < 0) | ||
| 245 | error("pipe"); | ||
| 246 | ctlfd = open("/chan/new/ctl", ORDWR); | ||
| 247 | buf := array[12] of byte; | ||
| 248 | if(ctlfd==nil || read(ctlfd, buf, 12)!=12) | ||
| 249 | error("ctl"); | ||
| 250 | id = int string buf; | ||
| 251 | buf = nil; | ||
| 252 | b := sprint("/chan/%d/tag", id); | ||
| 253 | fd = open(b, OWRITE); | ||
| 254 | write(fd, array of byte " Send Delete", 12); | ||
| 255 | fd = nil; | ||
| 256 | b = sprint("/chan/%d/event", id); | ||
| 257 | eventfd = open(b, ORDWR); | ||
| 258 | b = sprint("/chan/%d/addr", id); | ||
| 259 | addrfd = open(b, ORDWR); | ||
| 260 | b = sprint("/chan/%d/data", id); | ||
| 261 | datafd = open(b, ORDWR); # OCEXEC | ||
| 262 | if(eventfd==nil || addrfd==nil || datafd==nil) | ||
| 263 | error("data files"); | ||
| 264 | c = chan of int; | ||
| 265 | spawn run(program, id, c); | ||
| 266 | pid = <-c; | ||
| 267 | # b = sprint("/prog/%d/notepg", pid); | ||
| 268 | # pgrpfd = open(b, OWRITE); # OCEXEC | ||
| 269 | # if(pgrpfd == nil) | ||
| 270 | # fprint(stdout, "warning: win can't open notepg: %r\n"); | ||
| 271 | c <-= 1; | ||
| 272 | fd = open("/dev/acme/data", ORDWR); | ||
| 273 | if(fd == nil) | ||
| 274 | error("/dev/acme/data"); | ||
| 275 | wd := workdir->init(); | ||
| 276 | # b = sprint("name %s/-%s\n0\n", wd, name); | ||
| 277 | b = sprint("name %s/-%s\n", wd, name); | ||
| 278 | ab := array of byte b; | ||
| 279 | write(ctlfd, ab, len ab); | ||
| 280 | b = sprint("dumpdir %s/\n", wd); | ||
| 281 | ab = array of byte b; | ||
| 282 | write(ctlfd, ab, len ab); | ||
| 283 | b = sprint("dump %s\n", onestring(argv)); | ||
| 284 | ab = array of byte b; | ||
| 285 | write(ctlfd, ab, len ab); | ||
| 286 | ab = nil; | ||
| 287 | spawn stdinx(fd, ctlfd, eventfd, addrfd, datafd); | ||
| 288 | stdoutx(fd, addrfd, datafd); | ||
| 289 | } | ||
| 290 | |||
| 291 | run(argv : list of string, id : int, c : chan of int) | ||
| 292 | { | ||
| 293 | fd0, fd1 : ref FD; | ||
| 294 | |||
| 295 | pctl(FORKENV|FORKFD|NEWPGRP, nil); # had RFMEM | ||
| 296 | c <-= pctl(0, nil); | ||
| 297 | <-c; | ||
| 298 | pctl(FORKNS, nil); | ||
| 299 | if(bind("/dev/acme/data1", "/dev/cons", MREPL) < 0){ | ||
| 300 | fprint(stderr, "can't bind /dev/cons: %r\n"); | ||
| 301 | exit; | ||
| 302 | } | ||
| 303 | fd0 = open("/dev/cons", OREAD); | ||
| 304 | fd1 = open("/dev/cons", OWRITE); | ||
| 305 | if(fd0==nil || fd1==nil){ | ||
| 306 | fprint(stderr, "can't open /dev/cons: %r\n"); | ||
| 307 | exit; | ||
| 308 | } | ||
| 309 | dup(fd0.fd, 0); | ||
| 310 | dup(fd1.fd, 1); | ||
| 311 | dup(fd1.fd, 2); | ||
| 312 | fd0 = fd1 = nil; | ||
| 313 | b := sprint("/chan/%d", id); | ||
| 314 | if(bind(b, "/dev/acme", MREPL) < 0) | ||
| 315 | error("bind /dev/acme"); | ||
| 316 | if(bind(sprint("/chan/%d/consctl", id), "/dev/consctl", MREPL) < 0) | ||
| 317 | error("bind /dev/consctl"); | ||
| 318 | exec(hd argv, argv); | ||
| 319 | exit; | ||
| 320 | } | ||
| 321 | |||
| 322 | killing : int = 0; | ||
| 323 | |||
| 324 | error(s : string) | ||
| 325 | { | ||
| 326 | if(s != nil) | ||
| 327 | fprint(stderr, "win: %s: %r\n", s); | ||
| 328 | if (killing) | ||
| 329 | return; | ||
| 330 | killing = 1; | ||
| 331 | s = "kill"; | ||
| 332 | if(pid) | ||
| 333 | postnote(PNGROUP, pid, s); | ||
| 334 | # write(pgrpfd, array of byte "hangup", 6); | ||
| 335 | postnote(PNPROC, lockpid, s); | ||
| 336 | postnote(PNGROUP, parentpid, s); | ||
| 337 | exit; | ||
| 338 | } | ||
| 339 | |||
| 340 | buff := array[8192] of byte; | ||
| 341 | bufp : int; | ||
| 342 | nbuf : int; | ||
| 343 | |||
| 344 | onestring(argv : list of string) : string | ||
| 345 | { | ||
| 346 | s : string; | ||
| 347 | |||
| 348 | if(argv == nil) | ||
| 349 | return ""; | ||
| 350 | for( ; argv != nil; argv = tl argv){ | ||
| 351 | s += hd argv; | ||
| 352 | if (tl argv != nil) | ||
| 353 | s += " "; | ||
| 354 | } | ||
| 355 | return s; | ||
| 356 | } | ||
| 357 | |||
| 358 | getec(efd : ref FD) : int | ||
| 359 | { | ||
| 360 | if(nbuf == 0){ | ||
| 361 | nbuf = read(efd, buff, len buff); | ||
| 362 | if(nbuf <= 0) | ||
| 363 | error(nil); | ||
| 364 | bufp = 0; | ||
| 365 | } | ||
| 366 | --nbuf; | ||
| 367 | return int buff[bufp++]; | ||
| 368 | } | ||
| 369 | |||
| 370 | geten(efd : ref FD) : int | ||
| 371 | { | ||
| 372 | n, c : int; | ||
| 373 | |||
| 374 | n = 0; | ||
| 375 | while('0'<=(c=getec(efd)) && c<='9') | ||
| 376 | n = n*10+(c-'0'); | ||
| 377 | if(c != ' ') | ||
| 378 | error("event number syntax"); | ||
| 379 | return n; | ||
| 380 | } | ||
| 381 | |||
| 382 | geter(efd : ref FD, buf : array of byte) : (int, int) | ||
| 383 | { | ||
| 384 | r, m, n, ok : int; | ||
| 385 | |||
| 386 | r = getec(efd); | ||
| 387 | buf[0] = byte r; | ||
| 388 | n = 1; | ||
| 389 | if(r < Runeself) | ||
| 390 | return (r, n); | ||
| 391 | for (;;) { | ||
| 392 | (r, m, ok) = byte2char(buf[0:n], 0); | ||
| 393 | if (m > 0) | ||
| 394 | return (r, n); | ||
| 395 | buf[n++] = byte getec(efd); | ||
| 396 | } | ||
| 397 | return (0, 0); | ||
| 398 | } | ||
| 399 | |||
| 400 | gete(efd : ref FD, e : ref Event) | ||
| 401 | { | ||
| 402 | i, nb : int; | ||
| 403 | |||
| 404 | e.c1 = getec(efd); | ||
| 405 | e.c2 = getec(efd); | ||
| 406 | e.q0 = geten(efd); | ||
| 407 | e.q1 = geten(efd); | ||
| 408 | e.flag = geten(efd); | ||
| 409 | e.nr = geten(efd); | ||
| 410 | if(e.nr > EVENTSIZE) | ||
| 411 | error("event string too long"); | ||
| 412 | e.nb = 0; | ||
| 413 | for(i=0; i<e.nr; i++){ | ||
| 414 | (e.r[i], nb) = geter(efd, e.b[e.nb:]); | ||
| 415 | e.nb += nb; | ||
| 416 | } | ||
| 417 | e.r[e.nr] = 0; | ||
| 418 | e.b[e.nb] = byte 0; | ||
| 419 | if(getec(efd) != '\n') | ||
| 420 | error("event syntax 2"); | ||
| 421 | } | ||
| 422 | |||
| 423 | nrunes(s : array of byte, nb : int) : int | ||
| 424 | { | ||
| 425 | i, n, r, b, ok : int; | ||
| 426 | |||
| 427 | n = 0; | ||
| 428 | for(i=0; i<nb; n++) { | ||
| 429 | (r, b, ok) = byte2char(s, i); | ||
| 430 | if (b == 0) | ||
| 431 | error("not full string in nrunes()"); | ||
| 432 | i += b; | ||
| 433 | } | ||
| 434 | return n; | ||
| 435 | } | ||
| 436 | |||
| 437 | stdinx(fd0 : ref FD, cfd : ref FD, efd : ref FD, afd : ref FD, dfd : ref FD) | ||
| 438 | { | ||
| 439 | e, e2, e3, e4 : ref Event; | ||
| 440 | |||
| 441 | e = newevent(EVENTSIZE); | ||
| 442 | e2 = newevent(EVENTSIZE); | ||
| 443 | e3 = newevent(EVENTSIZE); | ||
| 444 | e4 = newevent(EVENTSIZE); | ||
| 445 | for(;;){ | ||
| 446 | gete(efd, e); | ||
| 447 | q.l.lock(); | ||
| 448 | case(e.c1){ | ||
| 449 | 'E' => # write to body; can't affect us | ||
| 450 | break; | ||
| 451 | 'F' => # generated by our actions; ignore | ||
| 452 | break; | ||
| 453 | 'K' or 'M' => | ||
| 454 | case(e.c2){ | ||
| 455 | 'R' => | ||
| 456 | addtype(' ', ntyper, e.b, e.nb, e.nr); | ||
| 457 | sendtype(fd0, 1); | ||
| 458 | break; | ||
| 459 | 'I' => | ||
| 460 | if(e.q0 < q.p) | ||
| 461 | q.p += e.q1-e.q0; | ||
| 462 | else if(e.q0 <= q.p+ntyper) | ||
| 463 | typex(e, fd0, afd, dfd); | ||
| 464 | break; | ||
| 465 | 'D' => | ||
| 466 | q.p -= delete(e); | ||
| 467 | break; | ||
| 468 | 'x' or 'X' => | ||
| 469 | if(e.flag & 2) | ||
| 470 | gete(efd, e2); | ||
| 471 | if(e.flag & 8){ | ||
| 472 | gete(efd, e3); | ||
| 473 | gete(efd, e4); | ||
| 474 | } | ||
| 475 | if(e.flag&1 || (e.c2=='x' && e.nr==0 && e2.nr==0)){ | ||
| 476 | # send it straight back | ||
| 477 | fprint(efd, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1); | ||
| 478 | break; | ||
| 479 | } | ||
| 480 | if(e.q0==e.q1 && (e.flag&2)){ | ||
| 481 | e2.flag = e.flag; | ||
| 482 | *e = *e2; | ||
| 483 | } | ||
| 484 | if(e.flag & 8){ | ||
| 485 | if(e.q1 != e.q0){ | ||
| 486 | send(e, fd0, cfd, afd, dfd, 0); | ||
| 487 | send(blank, fd0, cfd, afd, dfd, 0); | ||
| 488 | } | ||
| 489 | send(e3, fd0, cfd, afd, dfd, 1); | ||
| 490 | }else if(e.q1 != e.q0) | ||
| 491 | send(e, fd0, cfd, afd, dfd, 1); | ||
| 492 | break; | ||
| 493 | 'l' or 'L' => | ||
| 494 | # just send it back | ||
| 495 | if(e.flag & 2) | ||
| 496 | gete(efd, e2); | ||
| 497 | fprint(efd, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1); | ||
| 498 | break; | ||
| 499 | 'd' or 'i' => | ||
| 500 | break; | ||
| 501 | * => | ||
| 502 | fprint(stdout, "unknown message %c%c\n", e.c1, e.c2); | ||
| 503 | break; | ||
| 504 | } | ||
| 505 | * => | ||
| 506 | fprint(stdout, "unknown message %c%c\n", e.c1, e.c2); | ||
| 507 | break; | ||
| 508 | } | ||
| 509 | q.l.unlock(); | ||
| 510 | } | ||
| 511 | } | ||
| 512 | |||
| 513 | stdoutx(fd1 : ref FD, afd : ref FD, dfd : ref FD) | ||
| 514 | { | ||
| 515 | n, m, w, npart : int; | ||
| 516 | s, t : int; | ||
| 517 | buf, hold, x : array of byte; | ||
| 518 | r, ok : int; | ||
| 519 | |||
| 520 | buf = array[8192+UTFmax+1] of byte; | ||
| 521 | hold = array[UTFmax] of byte; | ||
| 522 | npart = 0; | ||
| 523 | for(;;){ | ||
| 524 | n = read(fd1, buf[npart:], 8192); | ||
| 525 | if(n < 0) | ||
| 526 | error(nil); | ||
| 527 | if(n == 0) | ||
| 528 | continue; | ||
| 529 | |||
| 530 | # squash NULs | ||
| 531 | for (s = 0; s < n; s++) | ||
| 532 | if (buf[npart+s] == byte 0) | ||
| 533 | break; | ||
| 534 | if(s < n){ | ||
| 535 | for(t=s; s<n; s++) | ||
| 536 | if(buf[npart+t] == buf[npart+s]) # assign = | ||
| 537 | t++; | ||
| 538 | n = t; | ||
| 539 | } | ||
| 540 | |||
| 541 | n += npart; | ||
| 542 | |||
| 543 | # hold on to final partial rune | ||
| 544 | npart = 0; | ||
| 545 | while(n>0 && (int buf[n-1]&16rC0)){ | ||
| 546 | --n; | ||
| 547 | npart++; | ||
| 548 | if((int buf[n]&16rC0)!=16r80){ | ||
| 549 | if(utfbytes(buf[n:], npart) > 0){ | ||
| 550 | (r, w, ok) = byte2char(buf, n); | ||
| 551 | n += w; | ||
| 552 | npart -= w; | ||
| 553 | } | ||
| 554 | break; | ||
| 555 | } | ||
| 556 | } | ||
| 557 | if(n > 0){ | ||
| 558 | hold[0:] = buf[n:n+npart]; | ||
| 559 | buf[n] = byte 0; | ||
| 560 | q.l.lock(); | ||
| 561 | str := sprint("#%d", q.p); | ||
| 562 | x = array of byte str; | ||
| 563 | m = len x; | ||
| 564 | if(write(afd, x, m) != m) | ||
| 565 | error("stdout writing address"); | ||
| 566 | x = nil; | ||
| 567 | if(write(dfd, buf, n) != n) | ||
| 568 | error("stdout writing body"); | ||
| 569 | q.p += nrunes(buf, n); | ||
| 570 | q.l.unlock(); | ||
| 571 | buf[0:] = hold[0:npart]; | ||
| 572 | } | ||
| 573 | } | ||
| 574 | } | ||
| 575 | |||
| 576 | delete(e : ref Event) : int | ||
| 577 | { | ||
| 578 | q0, q1 : int; | ||
| 579 | deltap : int; | ||
| 580 | |||
| 581 | q0 = e.q0; | ||
| 582 | q1 = e.q1; | ||
| 583 | if(q1 <= q.p) | ||
| 584 | return e.q1-e.q0; | ||
| 585 | if(q0 >= q.p+ntyper) | ||
| 586 | return 0; | ||
| 587 | deltap = 0; | ||
| 588 | if(q0 < q.p){ | ||
| 589 | deltap = q.p-q0; | ||
| 590 | q0 = 0; | ||
| 591 | }else | ||
| 592 | q0 -= q.p; | ||
| 593 | if(q1 > q.p+ntyper) | ||
| 594 | q1 = ntyper; | ||
| 595 | else | ||
| 596 | q1 -= q.p; | ||
| 597 | deltype(q0, q1); | ||
| 598 | return deltap; | ||
| 599 | } | ||
| 600 | |||
| 601 | addtype(c : int, p0 : int, b : array of byte, nb : int, nr : int) | ||
| 602 | { | ||
| 603 | i, w : int; | ||
| 604 | r, ok : int; | ||
| 605 | p : int; | ||
| 606 | b0 : int; | ||
| 607 | |||
| 608 | for(i=0; i<nb; i+=w){ | ||
| 609 | (r, w, ok) = byte2char(b, i); | ||
| 610 | if(r==16r7F && c=='K'){ | ||
| 611 | if (pid) | ||
| 612 | postnote(PNGROUP, pid, "kill"); | ||
| 613 | # write(pgrpfd, array of byte "interrupt", 9); | ||
| 614 | # toss all typing | ||
| 615 | q.p += ntyper+nr; | ||
| 616 | ntypebreak = 0; | ||
| 617 | ntypeb = 0; | ||
| 618 | ntyper = 0; | ||
| 619 | # buglet: more than one delete ignored | ||
| 620 | return; | ||
| 621 | } | ||
| 622 | if(r=='\n' || r==16r04) | ||
| 623 | ntypebreak++; | ||
| 624 | } | ||
| 625 | ot := typing; | ||
| 626 | typing = array[ntypeb+nb] of byte; | ||
| 627 | if(typing == nil) | ||
| 628 | error("realloc"); | ||
| 629 | if (ot != nil) | ||
| 630 | typing[0:] = ot[0:ntypeb]; | ||
| 631 | ot = nil; | ||
| 632 | if(p0 == ntyper) | ||
| 633 | typing[ntypeb:] = b[0:nb]; | ||
| 634 | else{ | ||
| 635 | b0 = 0; | ||
| 636 | for(p=0; p<p0 && b0<ntypeb; p++){ | ||
| 637 | (r, w, ok) = byte2char(typing[b0:], i); | ||
| 638 | b0 += w; | ||
| 639 | } | ||
| 640 | if(p != p0) | ||
| 641 | error("typing: findrune"); | ||
| 642 | typing[b0+nb:] = typing[b0:ntypeb]; | ||
| 643 | typing[b0:] = b[0:nb]; | ||
| 644 | } | ||
| 645 | ntypeb += nb; | ||
| 646 | ntyper += nr; | ||
| 647 | } | ||
| 648 | |||
| 649 | sendtype(fd0 : ref FD, raw : int) | ||
| 650 | { | ||
| 651 | i, n, nr : int; | ||
| 652 | |||
| 653 | while(ntypebreak){ | ||
| 654 | brkc := 0; | ||
| 655 | for(i=0; i<ntypeb; i++) | ||
| 656 | if(typing[i]==byte '\n' || typing[i]==byte 16r04){ | ||
| 657 | n = i + (typing[i] == byte '\n'); | ||
| 658 | i++; | ||
| 659 | if(write(fd0, typing, n) != n) | ||
| 660 | error("sending to program"); | ||
| 661 | nr = nrunes(typing, i); | ||
| 662 | if (!raw) | ||
| 663 | q.p += nr; | ||
| 664 | ntyper -= nr; | ||
| 665 | ntypeb -= i; | ||
| 666 | typing[0:] = typing[i:i+ntypeb]; | ||
| 667 | ntypebreak--; | ||
| 668 | brkc = 1; | ||
| 669 | } | ||
| 670 | if (!brkc) { | ||
| 671 | fprint(stdout, "no breakchar\n"); | ||
| 672 | ntypebreak = 0; | ||
| 673 | } | ||
| 674 | } | ||
| 675 | } | ||
| 676 | |||
| 677 | deltype(p0 : int, p1 : int) | ||
| 678 | { | ||
| 679 | w : int; | ||
| 680 | p, b0, b1 : int; | ||
| 681 | r, ok : int; | ||
| 682 | |||
| 683 | # advance to p0 | ||
| 684 | b0 = 0; | ||
| 685 | for(p=0; p<p0 && b0<ntypeb; p++){ | ||
| 686 | (r, w, ok) = byte2char(typing, b0); | ||
| 687 | b0 += w; | ||
| 688 | } | ||
| 689 | if(p != p0) | ||
| 690 | error("deltype 1"); | ||
| 691 | # advance to p1 | ||
| 692 | b1 = b0; | ||
| 693 | for(; p<p1 && b1<ntypeb; p++){ | ||
| 694 | (r, w, ok) = byte2char(typing, b1); | ||
| 695 | b1 += w; | ||
| 696 | if(r=='\n' || r==16r04) | ||
| 697 | ntypebreak--; | ||
| 698 | } | ||
| 699 | if(p != p1) | ||
| 700 | error("deltype 2"); | ||
| 701 | typing[b0:] = typing[b1:ntypeb]; | ||
| 702 | ntypeb -= b1-b0; | ||
| 703 | ntyper -= p1-p0; | ||
| 704 | } | ||
| 705 | |||
| 706 | typex(e : ref Event, fd0 : ref FD, afd : ref FD, dfd : ref FD) | ||
| 707 | { | ||
| 708 | m, n, nr : int; | ||
| 709 | buf : array of byte; | ||
| 710 | |||
| 711 | if(e.nr > 0) | ||
| 712 | addtype(e.c1, e.q0-q.p, e.b, e.nb, e.nr); | ||
| 713 | else{ | ||
| 714 | buf = array[128] of byte; | ||
| 715 | m = e.q0; | ||
| 716 | while(m < e.q1){ | ||
| 717 | str := sprint("#%d", m); | ||
| 718 | b := array of byte str; | ||
| 719 | n = len b; | ||
| 720 | write(afd, b, n); | ||
| 721 | b = nil; | ||
| 722 | n = read(dfd, buf, len buf); | ||
| 723 | nr = nrunes(buf, n); | ||
| 724 | while(m+nr > e.q1){ | ||
| 725 | do; while(n>0 && (int buf[--n]&16rC0)==16r80); | ||
| 726 | --nr; | ||
| 727 | } | ||
| 728 | if(n == 0) | ||
| 729 | break; | ||
| 730 | addtype(e.c1, m-q.p, buf, n, nr); | ||
| 731 | m += nr; | ||
| 732 | } | ||
| 733 | } | ||
| 734 | buf = nil; | ||
| 735 | sendtype(fd0, 0); | ||
| 736 | } | ||
| 737 | |||
| 738 | send(e : ref Event, fd0 : ref FD, cfd : ref FD, afd : ref FD, dfd : ref FD, donl : int) | ||
| 739 | { | ||
| 740 | l, m, n, nr, lastc, end : int; | ||
| 741 | abuf, buf : array of byte; | ||
| 742 | |||
| 743 | buf = array[128] of byte; | ||
| 744 | end = q.p+ntyper; | ||
| 745 | str := sprint("#%d", end); | ||
| 746 | abuf = array of byte str; | ||
| 747 | l = len abuf; | ||
| 748 | write(afd, abuf, l); | ||
| 749 | abuf = nil; | ||
| 750 | if(e.nr > 0){ | ||
| 751 | write(dfd, e.b, e.nb); | ||
| 752 | addtype(e.c1, ntyper, e.b, e.nb, e.nr); | ||
| 753 | lastc = e.r[e.nr-1]; | ||
| 754 | }else{ | ||
| 755 | m = e.q0; | ||
| 756 | lastc = 0; | ||
| 757 | while(m < e.q1){ | ||
| 758 | str = sprint("#%d", m); | ||
| 759 | abuf = array of byte str; | ||
| 760 | n = len abuf; | ||
| 761 | write(afd, abuf, n); | ||
| 762 | abuf = nil; | ||
| 763 | n = read(dfd, buf, len buf); | ||
| 764 | nr = nrunes(buf, n); | ||
| 765 | while(m+nr > e.q1){ | ||
| 766 | do; while(n>0 && (int buf[--n]&16rC0)==16r80); | ||
| 767 | --nr; | ||
| 768 | } | ||
| 769 | if(n == 0) | ||
| 770 | break; | ||
| 771 | str = sprint("#%d", end); | ||
| 772 | abuf = array of byte str; | ||
| 773 | l = len abuf; | ||
| 774 | write(afd, abuf, l); | ||
| 775 | abuf = nil; | ||
| 776 | write(dfd, buf, n); | ||
| 777 | addtype(e.c1, ntyper, buf, n, nr); | ||
| 778 | lastc = int buf[n-1]; | ||
| 779 | m += nr; | ||
| 780 | end += nr; | ||
| 781 | } | ||
| 782 | } | ||
| 783 | if(donl && lastc!='\n'){ | ||
| 784 | write(dfd, array of byte "\n", 1); | ||
| 785 | addtype(e.c1, ntyper, array of byte "\n", 1, 1); | ||
| 786 | } | ||
| 787 | write(cfd, array of byte "dot=addr", 8); | ||
| 788 | sendtype(fd0, 0); | ||
| 789 | buf = nil; | ||
| 790 | } | ||
| 791 | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | e file | x '/regexp/' | c 'replacement' | ||
| 2 | e 'file:0,$' | x '/.*word.*\n/' | p -n | ||
| 3 | e file | pipe command args ... | ||
| 4 | New /absolute/file/name | ||
| @@ -0,0 +1,24 @@ | |||
| 1 | <../../../../mkconfig | ||
| 2 | |||
| 3 | BIN=$ROOT/acme/edit | ||
| 4 | |||
| 5 | DIRS=\ | ||
| 6 | src\ | ||
| 7 | |||
| 8 | TARG=\ | ||
| 9 | guide\ | ||
| 10 | readme\ | ||
| 11 | |||
| 12 | BINTARG=${TARG:%=$BIN/%} | ||
| 13 | |||
| 14 | all:V: $TARG | ||
| 15 | |||
| 16 | install:V: $BINTARG | ||
| 17 | |||
| 18 | $BIN/guide : guide | ||
| 19 | rm -f $BIN/guide && cp guide $BIN/guide | ||
| 20 | |||
| 21 | $BIN/readme : readme | ||
| 22 | rm -f $BIN/readme && cp readme $BIN/readme | ||
| 23 | |||
| 24 | <$ROOT/mkfiles/mksubdirs | ||
| @@ -0,0 +1,31 @@ | |||
| 1 | The programs collected in /acme/edit offer a sam-like command interface | ||
| 2 | to acme windows. The guide file | ||
| 3 | /acme/edit/guide | ||
| 4 | holds templates for several editing operations implemented | ||
| 5 | by external programs. These programs, composed in | ||
| 6 | a pipeline, refine the sections of a file to be modified. | ||
| 7 | Thus in sam when one says | ||
| 8 | x/.*\n/ g/foo/ p | ||
| 9 | in /acme/edit one runs | ||
| 10 | x '/.*\n/' | g '/foo/' | p | ||
| 11 | The e command, unrelated to e in sam, disambiguates file names, collects | ||
| 12 | lists of names, etc., and produces input suitable for the other tools. | ||
| 13 | For example: | ||
| 14 | e '/usr/rob/acme:0,$' | x /oldname/ | c /newname/ | ||
| 15 | changes oldname to newname in all the files loaded in acme whose names match | ||
| 16 | the literal text /usr/rob/acme. | ||
| 17 | |||
| 18 | The commands in /acme/edit are | ||
| 19 | e | ||
| 20 | x | ||
| 21 | g | ||
| 22 | c | ||
| 23 | d | ||
| 24 | p | ||
| 25 | pipe (like sam's | , which can't be used for syntactic reasons) | ||
| 26 | |||
| 27 | p takes a -n flag analogous to grep's -n. There is no s command. | ||
| 28 | e has a -l flag to produce line numbers instead of the default character numbers. | ||
| 29 | Its implementation is poor but sufficient for the mundane job of recreating | ||
| 30 | the occasional line number for tools like acid; its use with the other commands | ||
| 31 | in this directory is discouraged. | ||
| @@ -0,0 +1,89 @@ | |||
| 1 | implement Aa; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | |||
| 7 | sys : Sys; | ||
| 8 | bufio : Bufio; | ||
| 9 | |||
| 10 | ORDWR, FD, open, read, write, seek, sprint, fprint, fildes, byte2char : import sys; | ||
| 11 | Iobuf : import bufio; | ||
| 12 | |||
| 13 | Aa : module { | ||
| 14 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 15 | }; | ||
| 16 | |||
| 17 | stdin, stderr : ref FD; | ||
| 18 | |||
| 19 | init(nil : ref Draw->Context, argl : list of string) | ||
| 20 | { | ||
| 21 | sys = load Sys Sys->PATH; | ||
| 22 | bufio = load Bufio Bufio->PATH; | ||
| 23 | stdin = fildes(0); | ||
| 24 | stderr = fildes(2); | ||
| 25 | main(argl); | ||
| 26 | } | ||
| 27 | |||
| 28 | include "findfile.b"; | ||
| 29 | |||
| 30 | prog := "a"; | ||
| 31 | bin : ref Iobuf; | ||
| 32 | |||
| 33 | main(argv : list of string) | ||
| 34 | { | ||
| 35 | afd, cfd, dfd : ref FD; | ||
| 36 | i, id : int; | ||
| 37 | nf, n, seq, rlen : int; | ||
| 38 | f, tf : array of File; | ||
| 39 | buf, s : string; | ||
| 40 | |||
| 41 | if(len argv != 2){ | ||
| 42 | fprint(stderr, "usage: %s 'replacement'\n", prog); | ||
| 43 | exit; | ||
| 44 | } | ||
| 45 | |||
| 46 | include "input.b"; | ||
| 47 | |||
| 48 | # sort back to original order, backwards | ||
| 49 | qsort(f, nf, BSCMP); | ||
| 50 | |||
| 51 | # change | ||
| 52 | id = -1; | ||
| 53 | afd = nil; | ||
| 54 | cfd = nil; | ||
| 55 | dfd = nil; | ||
| 56 | ab := array of byte hd tl argv; | ||
| 57 | rlen = len ab; | ||
| 58 | for(i=0; i<nf; i++){ | ||
| 59 | if(f[i].ok == 0) | ||
| 60 | continue; | ||
| 61 | if(f[i].id != id){ | ||
| 62 | if(id > 0){ | ||
| 63 | afd = nil; | ||
| 64 | cfd = nil; | ||
| 65 | dfd = nil; | ||
| 66 | } | ||
| 67 | id = f[i].id; | ||
| 68 | buf = sprint("/mnt/acme/%d/addr", id); | ||
| 69 | afd = open(buf, ORDWR); | ||
| 70 | if(afd == nil) | ||
| 71 | rerror(buf); | ||
| 72 | buf = sprint("/mnt/acme/%d/data", id); | ||
| 73 | dfd = open(buf, ORDWR); | ||
| 74 | if(dfd == nil) | ||
| 75 | rerror(buf); | ||
| 76 | buf = sprint("/mnt/acme/%d/ctl", id); | ||
| 77 | cfd = open(buf, ORDWR); | ||
| 78 | if(cfd == nil) | ||
| 79 | rerror(buf); | ||
| 80 | if(write(cfd, array of byte "mark\nnomark\n", 12) != 12) | ||
| 81 | rerror("setting nomark"); | ||
| 82 | } | ||
| 83 | if(fprint(afd, "#%d", f[i].q1) < 0) | ||
| 84 | rerror("writing address"); | ||
| 85 | if(write(dfd, ab, rlen) != rlen) | ||
| 86 | rerror("writing replacement"); | ||
| 87 | } | ||
| 88 | exit; | ||
| 89 | } | ||
| @@ -0,0 +1,104 @@ | |||
| 1 | implement Cc; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | |||
| 7 | sys : Sys; | ||
| 8 | bufio : Bufio; | ||
| 9 | |||
| 10 | ORDWR, FD, open, read, write, seek, sprint, fprint, fildes, byte2char : import sys; | ||
| 11 | Iobuf : import bufio; | ||
| 12 | |||
| 13 | Cc : module { | ||
| 14 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 15 | }; | ||
| 16 | |||
| 17 | stdin, stderr : ref FD; | ||
| 18 | |||
| 19 | init(nil : ref Draw->Context, argl : list of string) | ||
| 20 | { | ||
| 21 | sys = load Sys Sys->PATH; | ||
| 22 | bufio = load Bufio Bufio->PATH; | ||
| 23 | stdin = fildes(0); | ||
| 24 | stderr = fildes(2); | ||
| 25 | main(argl); | ||
| 26 | } | ||
| 27 | |||
| 28 | prog := "c"; | ||
| 29 | |||
| 30 | include "findfile.b"; | ||
| 31 | |||
| 32 | bin : ref Iobuf; | ||
| 33 | |||
| 34 | main(argv : list of string) | ||
| 35 | { | ||
| 36 | afd, cfd, dfd : ref FD; | ||
| 37 | i, j, id : int; | ||
| 38 | r : string; | ||
| 39 | nf, n, seq, rlen : int; | ||
| 40 | f, tf : array of File; | ||
| 41 | buf, s : string; | ||
| 42 | |||
| 43 | if(len argv != 2){ | ||
| 44 | fprint(stderr, "usage: %s 'replacement'\n", prog); | ||
| 45 | exit; | ||
| 46 | } | ||
| 47 | |||
| 48 | include "input.b"; | ||
| 49 | |||
| 50 | # sort back to original order, backwards | ||
| 51 | qsort(f, nf, BSCMP); | ||
| 52 | |||
| 53 | # change | ||
| 54 | id = -1; | ||
| 55 | afd = nil; | ||
| 56 | cfd = nil; | ||
| 57 | dfd = nil; | ||
| 58 | argv1 := hd tl argv; | ||
| 59 | rlen = len argv1; | ||
| 60 | r = argv1; | ||
| 61 | i = 0; | ||
| 62 | for(j=0; j<rlen; j++){ | ||
| 63 | r[i] = argv1[j]; | ||
| 64 | if(i>0 && r[i-1]=='\\'){ | ||
| 65 | if(r[i] == 'n') | ||
| 66 | r[--i] = '\n'; | ||
| 67 | else if(r[i]=='\\') | ||
| 68 | r[--i] = '\\'; | ||
| 69 | } | ||
| 70 | i++; | ||
| 71 | } | ||
| 72 | rlen = i; | ||
| 73 | ab := array of byte r[0:rlen]; | ||
| 74 | rlen = len ab; | ||
| 75 | for(i=0; i<nf; i++){ | ||
| 76 | if(f[i].ok == 0) | ||
| 77 | continue; | ||
| 78 | if(f[i].id != id){ | ||
| 79 | if(id > 0){ | ||
| 80 | afd = cfd = dfd = nil; | ||
| 81 | } | ||
| 82 | id = f[i].id; | ||
| 83 | buf = sprint("/mnt/acme/%d/addr", id); | ||
| 84 | afd = open(buf, ORDWR); | ||
| 85 | if(afd == nil) | ||
| 86 | rerror(buf); | ||
| 87 | buf = sprint("/mnt/acme/%d/data", id); | ||
| 88 | dfd = open(buf, ORDWR); | ||
| 89 | if(dfd == nil) | ||
| 90 | rerror(buf); | ||
| 91 | buf = sprint("/mnt/acme/%d/ctl", id); | ||
| 92 | cfd = open(buf, ORDWR); | ||
| 93 | if(cfd == nil) | ||
| 94 | rerror(buf); | ||
| 95 | if(write(cfd, array of byte "mark\nnomark\n", 12) != 12) | ||
| 96 | rerror("setting nomark"); | ||
| 97 | } | ||
| 98 | if(fprint(afd, "#%d,#%d", f[i].q0, f[i].q1) < 0) | ||
| 99 | rerror("writing address"); | ||
| 100 | if(write(dfd, ab, rlen) != rlen) | ||
| 101 | rerror("writing replacement"); | ||
| 102 | } | ||
| 103 | exit; | ||
| 104 | } | ||
| @@ -0,0 +1,30 @@ | |||
| 1 | implement Dd; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "sh.m"; | ||
| 6 | |||
| 7 | Dd : module { | ||
| 8 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 9 | }; | ||
| 10 | |||
| 11 | init(ctxt : ref Draw->Context, argl : list of string) | ||
| 12 | { | ||
| 13 | sys := load Sys Sys->PATH; | ||
| 14 | stderr := sys->fildes(2); | ||
| 15 | if (len argl != 1) { | ||
| 16 | sys->fprint(stderr, "usage : d\n"); | ||
| 17 | return; | ||
| 18 | } | ||
| 19 | cmd := "/acme/edit/c"; | ||
| 20 | file := cmd + ".dis"; | ||
| 21 | c := load Command file; | ||
| 22 | if(c == nil) { | ||
| 23 | sys->fprint(stderr, "%s: %r\n", cmd); | ||
| 24 | return; | ||
| 25 | } | ||
| 26 | argl = nil; | ||
| 27 | argl = "" :: argl; | ||
| 28 | argl = cmd :: argl; | ||
| 29 | c->init(ctxt, argl); | ||
| 30 | } | ||
| @@ -0,0 +1,154 @@ | |||
| 1 | implement Ee; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | |||
| 7 | sys : Sys; | ||
| 8 | bufio : Bufio; | ||
| 9 | |||
| 10 | ORDWR, FD, open, read, write, seek, sprint, fprint, fildes, byte2char : import sys; | ||
| 11 | Iobuf : import bufio; | ||
| 12 | |||
| 13 | Ee : module { | ||
| 14 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 15 | }; | ||
| 16 | |||
| 17 | stdin, stdout, stderr : ref FD; | ||
| 18 | |||
| 19 | init(nil : ref Draw->Context, argl : list of string) | ||
| 20 | { | ||
| 21 | sys = load Sys Sys->PATH; | ||
| 22 | bufio = load Bufio Bufio->PATH; | ||
| 23 | stdin = fildes(0); | ||
| 24 | stdout = fildes(1); | ||
| 25 | stderr = fildes(2); | ||
| 26 | main(argl); | ||
| 27 | } | ||
| 28 | |||
| 29 | include "findfile.b"; | ||
| 30 | |||
| 31 | prog := "e"; | ||
| 32 | |||
| 33 | main(argv : list of string) | ||
| 34 | { | ||
| 35 | afd, cfd : ref FD; | ||
| 36 | i, id : int; | ||
| 37 | buf : string; | ||
| 38 | nf, n, lines, l0, l1 : int; | ||
| 39 | f, tf : array of File; | ||
| 40 | |||
| 41 | lines = 0; | ||
| 42 | if(len argv>1 && hd tl argv == "-l"){ | ||
| 43 | lines = 1; | ||
| 44 | argv = tl argv; | ||
| 45 | } | ||
| 46 | if(len argv < 2){ | ||
| 47 | fprint(stderr, "usage: %s 'file[:address]' ...\n", prog); | ||
| 48 | exit; | ||
| 49 | } | ||
| 50 | nf = 0; | ||
| 51 | f = nil; | ||
| 52 | for(argv = tl argv; argv != nil; argv = tl argv){ | ||
| 53 | (n, tf) = findfile(hd argv); | ||
| 54 | if(n == 0) | ||
| 55 | errors("no files match pattern", hd argv); | ||
| 56 | oldf := f; | ||
| 57 | f = array[n+nf] of File; | ||
| 58 | if(f == nil) | ||
| 59 | rerror("out of memory"); | ||
| 60 | if (oldf != nil) { | ||
| 61 | f[0:] = oldf[0:nf]; | ||
| 62 | oldf = nil; | ||
| 63 | } | ||
| 64 | f[nf:] = tf[0:n]; | ||
| 65 | nf += n; | ||
| 66 | tf = nil; | ||
| 67 | } | ||
| 68 | |||
| 69 | # convert to character positions | ||
| 70 | for(i=0; i<nf; i++){ | ||
| 71 | id = f[i].id; | ||
| 72 | buf = sprint("/mnt/acme/%d/addr", id); | ||
| 73 | afd = open(buf, ORDWR); | ||
| 74 | if(afd == nil) | ||
| 75 | rerror(buf); | ||
| 76 | buf = sprint("/mnt/acme/%d/ctl", id); | ||
| 77 | cfd = open(buf, ORDWR); | ||
| 78 | if(cfd == nil) | ||
| 79 | rerror(buf); | ||
| 80 | if(write(cfd, array of byte "addr=dot\n", 9) != 9) | ||
| 81 | rerror("setting address to dot"); | ||
| 82 | ab := array of byte f[i].addr; | ||
| 83 | if(write(afd, ab, len ab) != len ab){ | ||
| 84 | fprint(stderr, "%s: %s:%s is invalid address\n", prog, f[i].name, f[i].addr); | ||
| 85 | f[i].ok = 0; | ||
| 86 | afd = nil; | ||
| 87 | cfd = nil; | ||
| 88 | continue; | ||
| 89 | } | ||
| 90 | seek(afd, big 0, 0); | ||
| 91 | ab = array[24] of byte; | ||
| 92 | if(read(afd, ab, len ab) != 2*12) | ||
| 93 | rerror("reading address"); | ||
| 94 | afd = nil; | ||
| 95 | cfd = nil; | ||
| 96 | buf = string ab; | ||
| 97 | ab = nil; | ||
| 98 | f[i].q0 = int buf; | ||
| 99 | f[i].q1 = int buf[12:]; | ||
| 100 | f[i].ok = 1; | ||
| 101 | } | ||
| 102 | |||
| 103 | # sort | ||
| 104 | qsort(f, nf, FCMP); | ||
| 105 | |||
| 106 | |||
| 107 | for(i=0; i<nf; i++){ | ||
| 108 | if(f[i].ok) | ||
| 109 | if(lines){ | ||
| 110 | (l0, l1) = lineno(f[i]); | ||
| 111 | if(l1 > l0) | ||
| 112 | fprint(stdout, "%s:%d,%d\n", f[i].name, l0, l1); | ||
| 113 | else | ||
| 114 | fprint(stdout, "%s:%d\n", f[i].name, l0); | ||
| 115 | }else{ | ||
| 116 | if(f[i].q1 > f[i].q0) | ||
| 117 | fprint(stdout, "%s:#%d,#%d\n", f[i].name, f[i].q0, f[i].q1); | ||
| 118 | else | ||
| 119 | fprint(stdout, "%s:#%d\n", f[i].name, f[i].q0); | ||
| 120 | } | ||
| 121 | } | ||
| 122 | exit; | ||
| 123 | } | ||
| 124 | |||
| 125 | lineno(f : File) : (int, int) | ||
| 126 | { | ||
| 127 | b : ref Iobuf; | ||
| 128 | n0, n1, q, r : int; | ||
| 129 | buf : string; | ||
| 130 | |||
| 131 | buf = sprint("/mnt/acme/%d/body", f.id); | ||
| 132 | b = bufio->open(buf, bufio->OREAD); | ||
| 133 | if(b == nil){ | ||
| 134 | fprint(stderr, "%s: can't open %s: %r\n", prog, buf); | ||
| 135 | exit; | ||
| 136 | } | ||
| 137 | n0 = 1; | ||
| 138 | n1 = 1; | ||
| 139 | for(q=0; q<f.q1; q++){ | ||
| 140 | r = b.getc(); | ||
| 141 | if(r == bufio->EOF){ | ||
| 142 | fprint(stderr, "%s: early EOF on %s\n", prog, buf); | ||
| 143 | exit; | ||
| 144 | } | ||
| 145 | if(r=='\n'){ | ||
| 146 | if(q < f.q0) | ||
| 147 | n0++; | ||
| 148 | if(q+1 < f.q1) | ||
| 149 | n1++; | ||
| 150 | } | ||
| 151 | } | ||
| 152 | b.close(); | ||
| 153 | return (n0, n1); | ||
| 154 | } | ||
| @@ -0,0 +1,210 @@ | |||
| 1 | File : adt { | ||
| 2 | id : int; | ||
| 3 | seq : int; | ||
| 4 | ok : int; | ||
| 5 | q0, q1 : int; | ||
| 6 | name : string; | ||
| 7 | addr : string; | ||
| 8 | }; | ||
| 9 | |||
| 10 | BSCMP, SCMP, NCMP, FCMP : con iota; | ||
| 11 | |||
| 12 | indexfile := "/mnt/acme/index"; | ||
| 13 | |||
| 14 | dfd: ref Sys->FD; | ||
| 15 | debug(s : string) | ||
| 16 | { | ||
| 17 | if (dfd == nil) | ||
| 18 | dfd = sys->create("/usr/jrf/acme/debugedit", Sys->OWRITE, 8r600); | ||
| 19 | sys->fprint(dfd, "%s", s); | ||
| 20 | } | ||
| 21 | |||
| 22 | error(s : string) | ||
| 23 | { | ||
| 24 | fprint(stderr, "%s: %s\n", prog, s); | ||
| 25 | exit; | ||
| 26 | } | ||
| 27 | |||
| 28 | errors(s, t : string) | ||
| 29 | { | ||
| 30 | fprint(stderr, "%s: %s %s\n", prog, s, t); | ||
| 31 | exit; | ||
| 32 | } | ||
| 33 | |||
| 34 | rerror(s : string) | ||
| 35 | { | ||
| 36 | fprint(stderr, "%s: %s: %r\n", prog, s); | ||
| 37 | exit; | ||
| 38 | } | ||
| 39 | |||
| 40 | strcmp(s, t : string) : int | ||
| 41 | { | ||
| 42 | if (s < t) return -1; | ||
| 43 | if (s > t) return 1; | ||
| 44 | return 0; | ||
| 45 | } | ||
| 46 | |||
| 47 | strstr(s, t : string) : int | ||
| 48 | { | ||
| 49 | if (t == nil) | ||
| 50 | return 0; | ||
| 51 | n := len t; | ||
| 52 | if (n > len s) | ||
| 53 | return -1; | ||
| 54 | e := len s - n; | ||
| 55 | for (p := 0; p <= e; p++) | ||
| 56 | if (s[p:p+n] == t) | ||
| 57 | return p; | ||
| 58 | return -1; | ||
| 59 | } | ||
| 60 | |||
| 61 | nrunes(s : array of byte, nb : int) : int | ||
| 62 | { | ||
| 63 | i, n, r, b, ok : int; | ||
| 64 | |||
| 65 | n = 0; | ||
| 66 | for(i=0; i<nb; n++) { | ||
| 67 | (r, b, ok) = byte2char(s, i); | ||
| 68 | i += b; | ||
| 69 | } | ||
| 70 | return n; | ||
| 71 | } | ||
| 72 | |||
| 73 | index : ref Iobuf; | ||
| 74 | |||
| 75 | findfile(pat : string) : (int, array of File) | ||
| 76 | { | ||
| 77 | line, pat1, pat2 : string; | ||
| 78 | colon, blank : int; | ||
| 79 | n : int; | ||
| 80 | f : array of File; | ||
| 81 | |||
| 82 | if(index == nil) | ||
| 83 | index = bufio->open(indexfile, bufio->OREAD); | ||
| 84 | else | ||
| 85 | index.seek(big 0, 0); | ||
| 86 | if(index == nil) | ||
| 87 | rerror(indexfile); | ||
| 88 | for(colon=0; colon < len pat && pat[colon]!=':'; colon++) | ||
| 89 | ; | ||
| 90 | if (colon == len pat) { | ||
| 91 | pat1 = pat; | ||
| 92 | pat2 = "."; | ||
| 93 | } | ||
| 94 | else { | ||
| 95 | pat1 = pat[0:colon]; | ||
| 96 | pat2 = pat[colon+1:]; | ||
| 97 | } | ||
| 98 | n = 0; | ||
| 99 | f = nil; | ||
| 100 | while((line=index.gets('\n')) != nil){ | ||
| 101 | if(len line < 5*12) | ||
| 102 | rerror("bad index file format"); | ||
| 103 | line = line[0:len line - 1]; | ||
| 104 | for(blank=5*12; blank < len line && line[blank]!=' '; blank++) | ||
| 105 | ; | ||
| 106 | if (blank < len line) | ||
| 107 | line = line[0:blank]; | ||
| 108 | if(strcmp(line[5*12:], pat1) == 0){ | ||
| 109 | # exact match: take that | ||
| 110 | f = nil; # should also free t->addr's | ||
| 111 | f = array[1] of File; | ||
| 112 | if(f == nil) | ||
| 113 | rerror("out of memory"); | ||
| 114 | f[0].id = int line; | ||
| 115 | f[0].name = line[5*12:]; | ||
| 116 | f[0].addr = pat2; | ||
| 117 | n = 1; | ||
| 118 | break; | ||
| 119 | } | ||
| 120 | if(strstr(line[5*12:], pat1) >= 0){ | ||
| 121 | # partial match: add to list | ||
| 122 | off := f; | ||
| 123 | f = array[n+1] of File; | ||
| 124 | if(f == nil) | ||
| 125 | rerror("out of memory"); | ||
| 126 | f[0:] = off[0:n]; | ||
| 127 | off = nil; | ||
| 128 | f[n].id = int line; | ||
| 129 | f[n].name = line[5*12:]; | ||
| 130 | f[n].addr = pat2; | ||
| 131 | n++; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | return (n, f); | ||
| 135 | } | ||
| 136 | |||
| 137 | bscmp(a : File, b : File) : int | ||
| 138 | { | ||
| 139 | return b.seq - a.seq; | ||
| 140 | } | ||
| 141 | |||
| 142 | scmp(a : File, b : File) : int | ||
| 143 | { | ||
| 144 | return a.seq - b.seq; | ||
| 145 | } | ||
| 146 | |||
| 147 | ncmp(a : File, b : File) : int | ||
| 148 | { | ||
| 149 | return strcmp(a.name, b.name); | ||
| 150 | } | ||
| 151 | |||
| 152 | fcmp(a : File, b : File) : int | ||
| 153 | { | ||
| 154 | x : int; | ||
| 155 | |||
| 156 | if (a.name < b.name) | ||
| 157 | return -1; | ||
| 158 | if (a.name > b.name) | ||
| 159 | return 1; | ||
| 160 | x = a.q0 - b.q0; | ||
| 161 | if(x != 0) | ||
| 162 | return x; | ||
| 163 | return a.q1-b.q1; | ||
| 164 | } | ||
| 165 | |||
| 166 | gencmp(a : File, b : File, c : int) : int | ||
| 167 | { | ||
| 168 | if (c == BSCMP) | ||
| 169 | return bscmp(a, b); | ||
| 170 | if (c == SCMP) | ||
| 171 | return scmp(a, b); | ||
| 172 | if (c == NCMP) | ||
| 173 | return ncmp(a, b); | ||
| 174 | if (c == FCMP) | ||
| 175 | return fcmp(a, b); | ||
| 176 | return 0; | ||
| 177 | } | ||
| 178 | |||
| 179 | qsort(a : array of File, n : int, c : int) | ||
| 180 | { | ||
| 181 | i, j : int; | ||
| 182 | t : File; | ||
| 183 | |||
| 184 | while(n > 1) { | ||
| 185 | i = n>>1; | ||
| 186 | t = a[0]; a[0] = a[i]; a[i] = t; | ||
| 187 | i = 0; | ||
| 188 | j = n; | ||
| 189 | for(;;) { | ||
| 190 | do | ||
| 191 | i++; | ||
| 192 | while(i < n && gencmp(a[i], a[0], c) < 0); | ||
| 193 | do | ||
| 194 | j--; | ||
| 195 | while(j > 0 && gencmp(a[j], a[0], c) > 0); | ||
| 196 | if(j < i) | ||
| 197 | break; | ||
| 198 | t = a[i]; a[i] = a[j]; a[j] = t; | ||
| 199 | } | ||
| 200 | t = a[0]; a[0] = a[j]; a[j] = t; | ||
| 201 | n = n-j-1; | ||
| 202 | if(j >= n) { | ||
| 203 | qsort(a, j, c); | ||
| 204 | a = a[j+1:]; | ||
| 205 | } else { | ||
| 206 | qsort(a[j+1:], n, c); | ||
| 207 | n = j; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | } | ||
| @@ -0,0 +1,95 @@ | |||
| 1 | implement Gg; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | |||
| 7 | sys : Sys; | ||
| 8 | bufio : Bufio; | ||
| 9 | |||
| 10 | ORDWR, FD, open, read, write, seek, sprint, fprint, fildes, byte2char : import sys; | ||
| 11 | Iobuf : import bufio; | ||
| 12 | |||
| 13 | Gg : module { | ||
| 14 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 15 | }; | ||
| 16 | |||
| 17 | stdin, stdout, stderr : ref FD; | ||
| 18 | |||
| 19 | init(nil : ref Draw->Context, argl : list of string) | ||
| 20 | { | ||
| 21 | sys = load Sys Sys->PATH; | ||
| 22 | bufio = load Bufio Bufio->PATH; | ||
| 23 | stdin = fildes(0); | ||
| 24 | stdout = fildes(1); | ||
| 25 | stderr = fildes(2); | ||
| 26 | main(argl); | ||
| 27 | } | ||
| 28 | |||
| 29 | prog := "g"; | ||
| 30 | |||
| 31 | include "findfile.b"; | ||
| 32 | |||
| 33 | bin : ref Iobuf; | ||
| 34 | |||
| 35 | main(argv : list of string) | ||
| 36 | { | ||
| 37 | afd, cfd, dfd : ref FD; | ||
| 38 | i, id, seq : int; | ||
| 39 | nf, n, plen : int; | ||
| 40 | f, tf : array of File; | ||
| 41 | buf, s : string; | ||
| 42 | |||
| 43 | if(len argv!=2 || len hd tl argv==0 || (hd tl argv)[0]!='/'){ | ||
| 44 | fprint(stderr, "usage: %s '/regexp/'\n", prog); | ||
| 45 | exit; | ||
| 46 | } | ||
| 47 | |||
| 48 | include "input.b"; | ||
| 49 | |||
| 50 | # execute regexp | ||
| 51 | id = -1; | ||
| 52 | afd = nil; | ||
| 53 | dfd = nil; | ||
| 54 | cfd = nil; | ||
| 55 | bufb := array of byte hd tl argv; | ||
| 56 | plen = len bufb; | ||
| 57 | for(i=0; i<nf; i++){ | ||
| 58 | if(f[i].ok == 0) | ||
| 59 | continue; | ||
| 60 | if(f[i].id != id){ | ||
| 61 | if(id > 0){ | ||
| 62 | afd = cfd = dfd = nil; | ||
| 63 | } | ||
| 64 | id = f[i].id; | ||
| 65 | buf = sprint("/mnt/acme/%d/addr", id); | ||
| 66 | afd = open(buf, ORDWR); | ||
| 67 | if(afd == nil) | ||
| 68 | rerror(buf); | ||
| 69 | buf = sprint("/mnt/acme/%d/ctl", id); | ||
| 70 | cfd = open(buf, ORDWR); | ||
| 71 | if(cfd == nil) | ||
| 72 | rerror(buf); | ||
| 73 | buf = sprint("/mnt/acme/%d/data", id); | ||
| 74 | dfd = open(buf, ORDWR); | ||
| 75 | if(dfd == nil) | ||
| 76 | rerror(buf); | ||
| 77 | } | ||
| 78 | ab := array of byte f[i].addr; | ||
| 79 | n = len ab; | ||
| 80 | if(write(afd, ab, n)!=n || fprint(cfd, "limit=addr\n")<0){ | ||
| 81 | buf = sprint("%s:%s is invalid limit", f[i].name, f[i].addr); | ||
| 82 | rerror(buf); | ||
| 83 | } | ||
| 84 | if(fprint(afd, "#%d", f[i].q0) < 0) | ||
| 85 | rerror("can't set dot"); | ||
| 86 | # look for match | ||
| 87 | if(write(afd, bufb, plen) == plen){ | ||
| 88 | if(f[i].q0 == f[i].q1) | ||
| 89 | fprint(stdout, "%s:#%d\n", f[i].name, f[i].q0); | ||
| 90 | else | ||
| 91 | fprint(stdout, "%s:#%d,#%d\n", f[i].name, f[i].q0, f[i].q1); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | exit; | ||
| 95 | } | ||
| @@ -0,0 +1,88 @@ | |||
| 1 | implement Ii; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | |||
| 7 | sys : Sys; | ||
| 8 | bufio : Bufio; | ||
| 9 | |||
| 10 | ORDWR, FD, open, read, write, seek, sprint, fprint, fildes, byte2char : import sys; | ||
| 11 | Iobuf : import bufio; | ||
| 12 | |||
| 13 | Ii : module { | ||
| 14 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 15 | }; | ||
| 16 | |||
| 17 | stdin, stderr : ref FD; | ||
| 18 | |||
| 19 | init(nil : ref Draw->Context, argl : list of string) | ||
| 20 | { | ||
| 21 | sys = load Sys Sys->PATH; | ||
| 22 | bufio = load Bufio Bufio->PATH; | ||
| 23 | stdin = fildes(0); | ||
| 24 | stderr = fildes(2); | ||
| 25 | main(argl); | ||
| 26 | } | ||
| 27 | |||
| 28 | prog := "i"; | ||
| 29 | |||
| 30 | include "findfile.b"; | ||
| 31 | |||
| 32 | bin : ref Iobuf; | ||
| 33 | |||
| 34 | main(argv : list of string) | ||
| 35 | { | ||
| 36 | afd, cfd, dfd : ref FD; | ||
| 37 | i, id : int; | ||
| 38 | nf, n, seq, rlen : int; | ||
| 39 | f, tf : array of File; | ||
| 40 | s, buf : string; | ||
| 41 | |||
| 42 | if(len argv != 2){ | ||
| 43 | fprint(stderr, "usage: %s 'replacement'\n", prog); | ||
| 44 | exit; | ||
| 45 | } | ||
| 46 | |||
| 47 | include "input.b"; | ||
| 48 | |||
| 49 | # sort back to original order, backwards | ||
| 50 | qsort(f, nf, BSCMP); | ||
| 51 | |||
| 52 | # change | ||
| 53 | id = -1; | ||
| 54 | afd = nil; | ||
| 55 | cfd = nil; | ||
| 56 | dfd = nil; | ||
| 57 | ab := array of byte hd tl argv; | ||
| 58 | rlen = len ab; | ||
| 59 | for(i=0; i<nf; i++){ | ||
| 60 | if(f[i].ok == 0) | ||
| 61 | continue; | ||
| 62 | if(f[i].id != id){ | ||
| 63 | if(id > 0){ | ||
| 64 | afd = cfd = dfd = nil; | ||
| 65 | } | ||
| 66 | id = f[i].id; | ||
| 67 | buf = sprint("/mnt/acme/%d/addr", id); | ||
| 68 | afd = open(buf, ORDWR); | ||
| 69 | if(afd == nil) | ||
| 70 | rerror(buf); | ||
| 71 | buf = sprint("/mnt/acme/%d/data", id); | ||
| 72 | dfd = open(buf, ORDWR); | ||
| 73 | if(dfd == nil) | ||
| 74 | rerror(buf); | ||
| 75 | buf = sprint("/mnt/acme/%d/ctl", id); | ||
| 76 | cfd = open(buf, ORDWR); | ||
| 77 | if(cfd == nil) | ||
| 78 | rerror(buf); | ||
| 79 | if(write(cfd, array of byte "mark\nnomark\n", 12) != 12) | ||
| 80 | rerror("setting nomark"); | ||
| 81 | } | ||
| 82 | if(fprint(afd, "#%d", f[i].q0) < 0) | ||
| 83 | rerror("writing address"); | ||
| 84 | if(write(dfd, ab, rlen) != rlen) | ||
| 85 | rerror("writing replacement"); | ||
| 86 | } | ||
| 87 | exit; | ||
| 88 | } | ||
| @@ -0,0 +1,84 @@ | |||
| 1 | bin = bufio->fopen(stdin, bufio->OREAD); | ||
| 2 | seq = 0; | ||
| 3 | nf = 0; | ||
| 4 | f = nil; | ||
| 5 | while((s=bin.gets('\n')) != nil){ | ||
| 6 | s = s[0:len s - 1]; | ||
| 7 | (n, tf) = findfile(s); | ||
| 8 | if(n == 0) | ||
| 9 | errors("no files match input", s); | ||
| 10 | for(i=0; i<n; i++) | ||
| 11 | tf[i].seq = seq++; | ||
| 12 | off := f; | ||
| 13 | f = array[n+nf] of File; | ||
| 14 | if(f == nil) | ||
| 15 | rerror("out of memory"); | ||
| 16 | if (off != nil) { | ||
| 17 | f[0:] = off[0:nf]; | ||
| 18 | off = nil; | ||
| 19 | } | ||
| 20 | f[nf:] = tf[0:n]; | ||
| 21 | nf += n; | ||
| 22 | tf = nil; | ||
| 23 | } | ||
| 24 | |||
| 25 | # sort by file name | ||
| 26 | qsort(f, nf, NCMP); | ||
| 27 | |||
| 28 | # convert to character positions if necessary | ||
| 29 | for(i=0; i<nf; i++){ | ||
| 30 | f[i].ok = 1; | ||
| 31 | # see if it's easy | ||
| 32 | s = f[i].addr; | ||
| 33 | if(s[0]=='#'){ | ||
| 34 | s = s[1:]; | ||
| 35 | n = 0; | ||
| 36 | while(len s > 0 && '0'<=s[0] && s[0]<='9'){ | ||
| 37 | n = n*10+(s[0]-'0'); | ||
| 38 | s = s[1:]; | ||
| 39 | } | ||
| 40 | f[i].q0 = n; | ||
| 41 | if(len s == 0){ | ||
| 42 | f[i].q1 = n; | ||
| 43 | continue; | ||
| 44 | } | ||
| 45 | if(s[0] == ',') { | ||
| 46 | s = s[1:]; | ||
| 47 | n = 0; | ||
| 48 | while(len s > 0 && '0'<=s[0] && s[0]<='9'){ | ||
| 49 | n = n*10+(s[0]-'0'); | ||
| 50 | s = s[1:]; | ||
| 51 | } | ||
| 52 | f[i].q1 = n; | ||
| 53 | if(len s == 0) | ||
| 54 | continue; | ||
| 55 | } | ||
| 56 | } | ||
| 57 | id = f[i].id; | ||
| 58 | buf = sprint("/chan/%d/addr", id); | ||
| 59 | afd = open(buf, ORDWR); | ||
| 60 | if(afd == nil) | ||
| 61 | rerror(buf); | ||
| 62 | buf = sprint("/chan/%d/ctl", id); | ||
| 63 | cfd = open(buf, ORDWR); | ||
| 64 | if(cfd == nil) | ||
| 65 | rerror(buf); | ||
| 66 | if(write(cfd, array of byte "addr=dot\n", 9) != 9) | ||
| 67 | rerror("setting address to dot"); | ||
| 68 | ab := array of byte f[i].addr; | ||
| 69 | if(write(afd, ab, len ab) != len ab){ | ||
| 70 | fprint(stderr, "%s: %s:%s is invalid address\n", prog, f[i].name, f[i].addr); | ||
| 71 | f[i].ok = 0; | ||
| 72 | afd = cfd = nil; | ||
| 73 | continue; | ||
| 74 | } | ||
| 75 | seek(afd, big 0, 0); | ||
| 76 | bbuf := array[2*12] of byte; | ||
| 77 | if(read(afd, bbuf, len bbuf) != 2*12) | ||
| 78 | rerror("reading address"); | ||
| 79 | afd = cfd = nil; | ||
| 80 | buf = string bbuf; | ||
| 81 | bbuf = nil; | ||
| 82 | f[i].q0 = int buf; | ||
| 83 | f[i].q1 = int buf[12:]; | ||
| 84 | } | ||
| @@ -0,0 +1,23 @@ | |||
| 1 | <../../../../../mkconfig | ||
| 2 | |||
| 3 | TARG=\ | ||
| 4 | a.dis\ | ||
| 5 | c.dis\ | ||
| 6 | d.dis\ | ||
| 7 | e.dis\ | ||
| 8 | g.dis\ | ||
| 9 | i.dis\ | ||
| 10 | p.dis\ | ||
| 11 | x.dis\ | ||
| 12 | pipe.dis\ | ||
| 13 | |||
| 14 | MODULES=\ | ||
| 15 | |||
| 16 | SYSMODULES=\ | ||
| 17 | sh.m\ | ||
| 18 | sys.m\ | ||
| 19 | draw.m\ | ||
| 20 | |||
| 21 | DISBIN=$ROOT/acme/edit | ||
| 22 | |||
| 23 | <$ROOT/mkfiles/mkdis | ||
| @@ -0,0 +1,109 @@ | |||
| 1 | implement Pp; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | |||
| 7 | sys : Sys; | ||
| 8 | bufio : Bufio; | ||
| 9 | |||
| 10 | ORDWR, FD, open, read, write, seek, sprint, fprint, fildes, byte2char : import sys; | ||
| 11 | Iobuf : import bufio; | ||
| 12 | |||
| 13 | Pp : module { | ||
| 14 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 15 | }; | ||
| 16 | |||
| 17 | stdin, stdout, stderr : ref FD; | ||
| 18 | |||
| 19 | init(nil : ref Draw->Context, argl : list of string) | ||
| 20 | { | ||
| 21 | sys = load Sys Sys->PATH; | ||
| 22 | bufio = load Bufio Bufio->PATH; | ||
| 23 | stdin = fildes(0); | ||
| 24 | stdout = fildes(1); | ||
| 25 | stderr = fildes(2); | ||
| 26 | main(argl); | ||
| 27 | } | ||
| 28 | |||
| 29 | include "findfile.b"; | ||
| 30 | |||
| 31 | prog := "p"; | ||
| 32 | bin : ref Iobuf; | ||
| 33 | |||
| 34 | main(argv : list of string) | ||
| 35 | { | ||
| 36 | afd, cfd, dfd : ref FD; | ||
| 37 | i, id : int; | ||
| 38 | m, nr, nf, n, nflag, seq : int; | ||
| 39 | f, tf : array of File; | ||
| 40 | buf, s : string; | ||
| 41 | |||
| 42 | nflag = 0; | ||
| 43 | if(len argv==2 && hd tl argv == "-n"){ | ||
| 44 | argv = tl argv; | ||
| 45 | nflag = 1; | ||
| 46 | } | ||
| 47 | if(len argv != 1){ | ||
| 48 | fprint(stderr, "usage: %s [-n]\n", prog); | ||
| 49 | exit; | ||
| 50 | } | ||
| 51 | |||
| 52 | include "input.b"; | ||
| 53 | |||
| 54 | # sort back to original order | ||
| 55 | qsort(f, nf, SCMP); | ||
| 56 | |||
| 57 | |||
| 58 | id = -1; | ||
| 59 | afd = nil; | ||
| 60 | cfd = nil; | ||
| 61 | dfd = nil; | ||
| 62 | for(i=0; i<nf; i++){ | ||
| 63 | if(f[i].ok == 0) | ||
| 64 | continue; | ||
| 65 | if(f[i].id != id){ | ||
| 66 | if(id > 0){ | ||
| 67 | afd = cfd = dfd = nil; | ||
| 68 | } | ||
| 69 | id = f[i].id; | ||
| 70 | buf = sprint("/mnt/acme/%d/addr", id); | ||
| 71 | afd = open(buf, ORDWR); | ||
| 72 | if(afd == nil) | ||
| 73 | rerror(buf); | ||
| 74 | buf = sprint("/mnt/acme/%d/data", id); | ||
| 75 | dfd = open(buf, ORDWR); | ||
| 76 | if(dfd == nil) | ||
| 77 | rerror(buf); | ||
| 78 | buf = sprint("/mnt/acme/%d/ctl", id); | ||
| 79 | cfd = open(buf, ORDWR); | ||
| 80 | if(cfd == nil) | ||
| 81 | rerror(buf); | ||
| 82 | } | ||
| 83 | if(nflag){ | ||
| 84 | if(f[i].q1 > f[i].q0) | ||
| 85 | fprint(stdout, "%s:#%d,#%d: ", f[i].name, f[i].q0, f[i].q1); | ||
| 86 | else | ||
| 87 | fprint(stdout, "%s:#%d: ", f[i].name, f[i].q0); | ||
| 88 | } | ||
| 89 | m = f[i].q0; | ||
| 90 | while(m < f[i].q1){ | ||
| 91 | if(fprint(afd, "#%d", m) < 0){ | ||
| 92 | fprint(stderr, "%s: %s:%s is invalid address\n", prog, f[i].name, f[i].addr); | ||
| 93 | continue; | ||
| 94 | } | ||
| 95 | bbuf := array[512] of byte; | ||
| 96 | n = read(dfd, bbuf, len buf); | ||
| 97 | nr = nrunes(bbuf, n); | ||
| 98 | while(m+nr > f[i].q1){ | ||
| 99 | do; while(n>0 && (int bbuf[--n]&16rC0)==16r80); | ||
| 100 | --nr; | ||
| 101 | } | ||
| 102 | if(n == 0) | ||
| 103 | break; | ||
| 104 | write(stdout, bbuf, n); | ||
| 105 | m += nr; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | exit; | ||
| 109 | } | ||
| @@ -0,0 +1,212 @@ | |||
| 1 | implement Pipe; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | include "sh.m"; | ||
| 7 | |||
| 8 | sys : Sys; | ||
| 9 | bufio : Bufio; | ||
| 10 | |||
| 11 | UTFmax, ORDWR, NEWFD, FD, open, read, write, seek, sprint, fprint, fildes, byte2char, pipe, dup, pctl : import sys; | ||
| 12 | Iobuf : import bufio; | ||
| 13 | |||
| 14 | Pipe : module { | ||
| 15 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 16 | }; | ||
| 17 | |||
| 18 | stdin, stderr : ref FD; | ||
| 19 | pipectxt : ref Draw->Context; | ||
| 20 | |||
| 21 | init(ctxt : ref Draw->Context, argl : list of string) | ||
| 22 | { | ||
| 23 | pipectxt = ctxt; | ||
| 24 | sys = load Sys Sys->PATH; | ||
| 25 | bufio = load Bufio Bufio->PATH; | ||
| 26 | stdin = fildes(0); | ||
| 27 | stderr = fildes(2); | ||
| 28 | main(argl); | ||
| 29 | } | ||
| 30 | |||
| 31 | include "findfile.b"; | ||
| 32 | |||
| 33 | prog := "pipe"; | ||
| 34 | bin : ref Iobuf; | ||
| 35 | |||
| 36 | main(argv : list of string) | ||
| 37 | { | ||
| 38 | afd, dfd, cfd : ref FD; | ||
| 39 | nf, nc, nr, npart : int; | ||
| 40 | p1, p2 : array of ref FD; | ||
| 41 | i, n, id, seq : int; | ||
| 42 | buf : string; | ||
| 43 | tmp, data : array of byte; | ||
| 44 | s : string; | ||
| 45 | r, s0 : int; | ||
| 46 | f, tf : array of File; | ||
| 47 | q, q0, q1 : int; | ||
| 48 | cpid : chan of int; | ||
| 49 | w, ok : int; | ||
| 50 | |||
| 51 | if(len argv < 2){ | ||
| 52 | fprint(stderr, "usage: pipe command\n"); | ||
| 53 | exit; | ||
| 54 | } | ||
| 55 | |||
| 56 | include "input.b"; | ||
| 57 | |||
| 58 | # sort back to original order | ||
| 59 | qsort(f, nf, SCMP); | ||
| 60 | |||
| 61 | # pipe | ||
| 62 | id = -1; | ||
| 63 | afd = nil; | ||
| 64 | cfd = nil; | ||
| 65 | dfd = nil; | ||
| 66 | tmp = array[8192+UTFmax] of byte; | ||
| 67 | if(tmp == nil) | ||
| 68 | error("malloc"); | ||
| 69 | cpid = chan of int; | ||
| 70 | for(i=0; i<nf; i++){ | ||
| 71 | if(f[i].id != id){ | ||
| 72 | if(id > 0){ | ||
| 73 | afd = cfd = dfd = nil; | ||
| 74 | } | ||
| 75 | id = f[i].id; | ||
| 76 | buf = sprint("/mnt/acme/%d/addr", id); | ||
| 77 | afd = open(buf, ORDWR); | ||
| 78 | if(afd == nil) | ||
| 79 | rerror(buf); | ||
| 80 | buf = sprint("/mnt/acme/%d/data", id); | ||
| 81 | dfd = open(buf, ORDWR); | ||
| 82 | if(dfd == nil) | ||
| 83 | rerror(buf); | ||
| 84 | buf = sprint("/mnt/acme/%d/ctl", id); | ||
| 85 | cfd = open(buf, ORDWR); | ||
| 86 | if(cfd == nil) | ||
| 87 | rerror(buf); | ||
| 88 | if(write(cfd, array of byte "mark\nnomark\n", 12) != 12) | ||
| 89 | rerror("setting nomark"); | ||
| 90 | } | ||
| 91 | |||
| 92 | if(fprint(afd, "#%ud", f[i].q0) < 0) | ||
| 93 | rerror("writing address"); | ||
| 94 | |||
| 95 | q0 = f[i].q0; | ||
| 96 | q1 = f[i].q1; | ||
| 97 | # suck up data | ||
| 98 | data = array[(q1-q0)*UTFmax+1] of byte; | ||
| 99 | if(data == nil) | ||
| 100 | error("malloc failed\n"); | ||
| 101 | s0 = 0; | ||
| 102 | q = q0; | ||
| 103 | bbuf := array[12] of byte; | ||
| 104 | while(q < q1){ | ||
| 105 | nc = read(dfd, data[s0:], (q1-q)*UTFmax); | ||
| 106 | if(nc <= 0) | ||
| 107 | error("read error from acme"); | ||
| 108 | seek(afd, big 0, 0); | ||
| 109 | if(read(afd, bbuf, 12) != 12) | ||
| 110 | rerror("reading address"); | ||
| 111 | q = int string bbuf; | ||
| 112 | s0 += nc; | ||
| 113 | } | ||
| 114 | bbuf = nil; | ||
| 115 | s0 = 0; | ||
| 116 | for(nr=0; nr<q1-q0; nr++) { | ||
| 117 | (r, w, ok) = byte2char(data, s0); | ||
| 118 | s0 += w; | ||
| 119 | } | ||
| 120 | |||
| 121 | p1 = array[2] of ref FD; | ||
| 122 | p2 = array[2] of ref FD; | ||
| 123 | if(pipe(p1)<0 || pipe(p2)<0) | ||
| 124 | error("pipe"); | ||
| 125 | |||
| 126 | spawn run(tl argv, p1[0], p2[1], cpid); | ||
| 127 | <-cpid; | ||
| 128 | p1[0] = nil; | ||
| 129 | p2[1] = nil; | ||
| 130 | |||
| 131 | spawn send(data, s0, p1[1]); | ||
| 132 | p1[1] = nil; | ||
| 133 | |||
| 134 | # put back data | ||
| 135 | if(fprint(afd, "#%d,#%d", q0, q1) < 0) | ||
| 136 | rerror("writing address"); | ||
| 137 | |||
| 138 | npart = 0; | ||
| 139 | q1 = q0; | ||
| 140 | while((nc = read(p2[0], tmp[npart:], 8192)) > 0){ | ||
| 141 | nc += npart; | ||
| 142 | s0 = 0; | ||
| 143 | while(s0 <= nc-UTFmax){ | ||
| 144 | (r, w, ok) = byte2char(tmp, s0); | ||
| 145 | s0 += w; | ||
| 146 | q1++; | ||
| 147 | } | ||
| 148 | if(s0 > 0) | ||
| 149 | if(write(dfd, tmp, s0) != s0) | ||
| 150 | error("write error to acme"); | ||
| 151 | npart = nc - s0; | ||
| 152 | tmp[0:] = tmp[s0:s0+npart]; | ||
| 153 | } | ||
| 154 | p2[0] = nil; | ||
| 155 | if(npart){ | ||
| 156 | s0 = 0; | ||
| 157 | while(s0 < npart){ | ||
| 158 | (r, w, ok) = byte2char(tmp, s0); | ||
| 159 | s0 += w; | ||
| 160 | q1++; | ||
| 161 | } | ||
| 162 | if(write(dfd, tmp, npart) != npart) | ||
| 163 | error("write error to acme"); | ||
| 164 | } | ||
| 165 | if(fprint(afd, "#%d,#%d", q0, q1) < 0) | ||
| 166 | rerror("writing address"); | ||
| 167 | if(fprint(cfd, "dot=addr\n") < 0) | ||
| 168 | rerror("writing dot"); | ||
| 169 | data = nil; | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | run(argv : list of string, p1, p2 : ref FD, c : chan of int) | ||
| 174 | { | ||
| 175 | pctl(NEWFD, 0::1::2::p1.fd::p2.fd::nil); | ||
| 176 | dup(p1.fd, 0); | ||
| 177 | dup(p2.fd, 1); | ||
| 178 | c <-= pctl(0, nil); | ||
| 179 | exec(hd argv, argv); | ||
| 180 | fprint(stderr, "can't exec"); | ||
| 181 | exit; | ||
| 182 | } | ||
| 183 | |||
| 184 | send(buf : array of byte, nbuf : int, fd : ref FD) | ||
| 185 | { | ||
| 186 | if(write(fd, buf, nbuf) != nbuf) | ||
| 187 | error("write error to process"); | ||
| 188 | fd = nil; | ||
| 189 | } | ||
| 190 | |||
| 191 | exec(cmd : string, argl : list of string) | ||
| 192 | { | ||
| 193 | file := cmd; | ||
| 194 | if(len file<4 || file[len file-4:]!=".dis") | ||
| 195 | file += ".dis"; | ||
| 196 | |||
| 197 | c := load Command file; | ||
| 198 | if(c == nil) { | ||
| 199 | err := sys->sprint("%r"); | ||
| 200 | if(file[0]!='/' && file[0:2]!="./"){ | ||
| 201 | c = load Command "/dis/"+file; | ||
| 202 | if(c == nil) | ||
| 203 | err = sys->sprint("%r"); | ||
| 204 | } | ||
| 205 | if(c == nil){ | ||
| 206 | sys->fprint(stderr, "%s: %s\n", cmd, err); | ||
| 207 | return; | ||
| 208 | } | ||
| 209 | } | ||
| 210 | |||
| 211 | c->init(pipectxt, argl); | ||
| 212 | } | ||
| @@ -0,0 +1,123 @@ | |||
| 1 | implement Xx; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | |||
| 7 | sys : Sys; | ||
| 8 | bufio : Bufio; | ||
| 9 | |||
| 10 | ORDWR, FD, open, read, write, seek, sprint, fprint, fildes, byte2char : import sys; | ||
| 11 | Iobuf : import bufio; | ||
| 12 | |||
| 13 | Xx : module { | ||
| 14 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 15 | }; | ||
| 16 | |||
| 17 | stdin, stdout, stderr : ref FD; | ||
| 18 | |||
| 19 | init(nil : ref Draw->Context, argl : list of string) | ||
| 20 | { | ||
| 21 | sys = load Sys Sys->PATH; | ||
| 22 | bufio = load Bufio Bufio->PATH; | ||
| 23 | stdin = fildes(0); | ||
| 24 | stdout = fildes(1); | ||
| 25 | stderr = fildes(2); | ||
| 26 | main(argl); | ||
| 27 | } | ||
| 28 | |||
| 29 | include "findfile.b"; | ||
| 30 | |||
| 31 | prog := "x"; | ||
| 32 | bin : ref Iobuf; | ||
| 33 | |||
| 34 | main(argv : list of string) | ||
| 35 | { | ||
| 36 | afd, cfd, dfd : ref FD; | ||
| 37 | i, id, seq : int; | ||
| 38 | nf, n, plen : int; | ||
| 39 | addr, aq0, aq1, matched : int; | ||
| 40 | f, tf : array of File; | ||
| 41 | buf, s : string; | ||
| 42 | bbuf0 : array of byte; | ||
| 43 | |||
| 44 | if(len argv!=2 || len hd tl argv==0 || (hd tl argv)[0]!='/'){ | ||
| 45 | fprint(stderr, "usage: %s '/regexp/'\n", prog); | ||
| 46 | exit; | ||
| 47 | } | ||
| 48 | |||
| 49 | include "input.b"; | ||
| 50 | |||
| 51 | # execute regexp | ||
| 52 | id = -1; | ||
| 53 | afd = nil; | ||
| 54 | dfd = nil; | ||
| 55 | cfd = nil; | ||
| 56 | for(i=0; i<nf; i++){ | ||
| 57 | if(f[i].ok == 0) | ||
| 58 | continue; | ||
| 59 | if(f[i].id != id){ | ||
| 60 | if(id > 0){ | ||
| 61 | afd = cfd = dfd = nil; | ||
| 62 | } | ||
| 63 | id = f[i].id; | ||
| 64 | buf = sprint("/mnt/acme/%d/addr", id); | ||
| 65 | afd = open(buf, ORDWR); | ||
| 66 | if(afd == nil) | ||
| 67 | rerror(buf); | ||
| 68 | buf = sprint("/mnt/acme/%d/ctl", id); | ||
| 69 | cfd = open(buf, ORDWR); | ||
| 70 | if(cfd == nil) | ||
| 71 | rerror(buf); | ||
| 72 | buf = sprint("/mnt/acme/%d/data", id); | ||
| 73 | dfd = open(buf, ORDWR); | ||
| 74 | if(dfd == nil) | ||
| 75 | rerror(buf); | ||
| 76 | } | ||
| 77 | bbuf0 = array of byte f[i].addr; | ||
| 78 | n = len bbuf0; | ||
| 79 | if(write(afd, bbuf0, n)!=n || fprint(cfd, "limit=addr\n")<0){ | ||
| 80 | buf = sprint("%s:%s is invalid limit", f[i].name, f[i].addr); | ||
| 81 | rerror(buf); | ||
| 82 | } | ||
| 83 | if(fprint(afd, "#%d", f[i].q0) < 0) | ||
| 84 | rerror("can't set address"); | ||
| 85 | if(fprint(cfd, "dot=addr") < 0) | ||
| 86 | rerror("can't unset dot"); | ||
| 87 | addr = f[i].q0-1; | ||
| 88 | bbuf := array of byte hd tl argv; | ||
| 89 | plen = len bbuf; | ||
| 90 | matched = 0; | ||
| 91 | # scan for matches | ||
| 92 | for(;;){ | ||
| 93 | if(write(afd, bbuf, plen) != plen) | ||
| 94 | break; | ||
| 95 | seek(afd, big 0, 0); | ||
| 96 | bbuf0 = array[2*12] of byte; | ||
| 97 | if(read(afd, bbuf0, len bbuf0) != 2*12) | ||
| 98 | rerror("reading address"); | ||
| 99 | buf = string bbuf0; | ||
| 100 | bbuf0 = nil; | ||
| 101 | aq0 = int buf; | ||
| 102 | aq1 = int buf[12:]; | ||
| 103 | if(matched && aq1==aq0 && addr==aq1){ # repeated null match; advance | ||
| 104 | matched = 0; | ||
| 105 | addr++; | ||
| 106 | if(addr > f[i].q1) | ||
| 107 | break; | ||
| 108 | if(fprint(afd, "#%d", addr) < 0) | ||
| 109 | rerror("writing address"); | ||
| 110 | continue; | ||
| 111 | } | ||
| 112 | matched = 1; | ||
| 113 | if(aq0<addr || aq0>=f[i].q1 || aq1>f[i].q1) | ||
| 114 | break; | ||
| 115 | addr = aq1; | ||
| 116 | if(aq0 == aq1) | ||
| 117 | fprint(stdout, "%s:#%d\n", f[i].name, aq0); | ||
| 118 | else | ||
| 119 | fprint(stdout, "%s:#%d,#%d\n", f[i].name, aq0, aq1); | ||
| 120 | } | ||
| 121 | } | ||
| 122 | exit; | ||
| 123 | } | ||
| @@ -0,0 +1,327 @@ | |||
| 1 | implement Ee; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | |||
| 7 | sys : Sys; | ||
| 8 | bufio : Bufio; | ||
| 9 | |||
| 10 | ORDWR, FD, open, read, write, seek, sprint, fprint, fildes, byte2char : import sys; | ||
| 11 | Iobuf : import bufio; | ||
| 12 | |||
| 13 | Ee : module { | ||
| 14 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 15 | }; | ||
| 16 | |||
| 17 | stdin, stdout, stderr : ref FD; | ||
| 18 | |||
| 19 | init(ctxt : ref Draw->Context, argl : list of string) | ||
| 20 | { | ||
| 21 | sys = load Sys Sys->PATH; | ||
| 22 | bufio = load Bufio Bufio->PATH; | ||
| 23 | stdin = fildes(0); | ||
| 24 | stdout = fildes(1); | ||
| 25 | stderr = fildes(2); | ||
| 26 | main(argl); | ||
| 27 | } | ||
| 28 | |||
| 29 | File : adt { | ||
| 30 | id : int; | ||
| 31 | seq : int; | ||
| 32 | ok : int; | ||
| 33 | q0, q1 : int; | ||
| 34 | name : string; | ||
| 35 | addr : string; | ||
| 36 | }; | ||
| 37 | |||
| 38 | BSCMP, SCMP, NCMP, FCMP : con iota; | ||
| 39 | |||
| 40 | indexfile := "/usr/jrf/tmp/index"; | ||
| 41 | |||
| 42 | dfd: ref Sys->FD; | ||
| 43 | debug(s : string) | ||
| 44 | { | ||
| 45 | if (dfd == nil) | ||
| 46 | dfd = sys->create("/usr/jrf/acme/debugedit", Sys->OWRITE, 8r600); | ||
| 47 | sys->fprint(dfd, "%s", s); | ||
| 48 | } | ||
| 49 | |||
| 50 | error(s : string) | ||
| 51 | { | ||
| 52 | debug(sys->sprint("error %s\n", s)); | ||
| 53 | fprint(stderr, "%s: %s\n", prog, s); | ||
| 54 | exit; | ||
| 55 | } | ||
| 56 | |||
| 57 | errors(s, t : string) | ||
| 58 | { | ||
| 59 | debug(sys->sprint("errors %s %s\n", s, t)); | ||
| 60 | fprint(stderr, "%s: %s %s\n", prog, s, t); | ||
| 61 | exit; | ||
| 62 | } | ||
| 63 | |||
| 64 | rerror(s : string) | ||
| 65 | { | ||
| 66 | debug(sys->sprint("rerror %s\n", s)); | ||
| 67 | fprint(stderr, "%s: %s: %r\n", prog, s); | ||
| 68 | exit; | ||
| 69 | } | ||
| 70 | |||
| 71 | strcmp(s, t : string) : int | ||
| 72 | { | ||
| 73 | if (s < t) return -1; | ||
| 74 | if (s > t) return 1; | ||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | strstr(s, t : string) : int | ||
| 79 | { | ||
| 80 | if (t == nil) | ||
| 81 | return 0; | ||
| 82 | n := len t; | ||
| 83 | if (n > len s) | ||
| 84 | return -1; | ||
| 85 | e := len s - n; | ||
| 86 | for (p := 0; p <= e; p++) | ||
| 87 | if (s[p:p+n] == t) | ||
| 88 | return p; | ||
| 89 | return -1; | ||
| 90 | } | ||
| 91 | |||
| 92 | nrunes(s : array of byte, nb : int) : int | ||
| 93 | { | ||
| 94 | i, n, r, b, ok : int; | ||
| 95 | |||
| 96 | n = 0; | ||
| 97 | for(i=0; i<nb; n++) { | ||
| 98 | (r, b, ok) = byte2char(s, i); | ||
| 99 | i += b; | ||
| 100 | } | ||
| 101 | return n; | ||
| 102 | } | ||
| 103 | |||
| 104 | index : ref Iobuf; | ||
| 105 | |||
| 106 | findfile(pat : string) : (int, array of File) | ||
| 107 | { | ||
| 108 | line, pat1, pat2 : string; | ||
| 109 | colon, blank : int; | ||
| 110 | n : int; | ||
| 111 | f : array of File; | ||
| 112 | |||
| 113 | if(index == nil) | ||
| 114 | index = bufio->open(indexfile, bufio->OREAD); | ||
| 115 | else | ||
| 116 | index.seek(0, 0); | ||
| 117 | if(index == nil) | ||
| 118 | rerror(indexfile); | ||
| 119 | for(colon=0; colon < len pat && pat[colon]!=':'; colon++) | ||
| 120 | ; | ||
| 121 | if (colon == len pat) { | ||
| 122 | pat1 = pat; | ||
| 123 | pat2 = "."; | ||
| 124 | } | ||
| 125 | else { | ||
| 126 | pat1 = pat[0:colon]; | ||
| 127 | pat2 = pat[colon+1:]; | ||
| 128 | } | ||
| 129 | n = 0; | ||
| 130 | f = nil; | ||
| 131 | while((line=index.gets('\n')) != nil){ | ||
| 132 | if(len line < 5*12) | ||
| 133 | rerror("bad index file format"); | ||
| 134 | line = line[0:len line - 1]; | ||
| 135 | for(blank=5*12; blank < len line && line[blank]!=' '; blank++) | ||
| 136 | ; | ||
| 137 | if (blank < len line) | ||
| 138 | line = line[0:blank]; | ||
| 139 | if(strcmp(line[5*12:], pat1) == 0){ | ||
| 140 | # exact match: take that | ||
| 141 | f = nil; # should also free t->addr's | ||
| 142 | f = array[1] of File; | ||
| 143 | if(f == nil) | ||
| 144 | rerror("out of memory"); | ||
| 145 | f[0].id = int line; | ||
| 146 | f[0].name = line[5*12:]; | ||
| 147 | f[0].addr = pat2; | ||
| 148 | n = 1; | ||
| 149 | break; | ||
| 150 | } | ||
| 151 | if(strstr(line[5*12:], pat1) >= 0){ | ||
| 152 | # partial match: add to list | ||
| 153 | off := f; | ||
| 154 | f = array[n+1] of File; | ||
| 155 | if(f == nil) | ||
| 156 | rerror("out of memory"); | ||
| 157 | f[0:] = off[0:n]; | ||
| 158 | off = nil; | ||
| 159 | f[n].id = int line; | ||
| 160 | f[n].name = line[5*12:]; | ||
| 161 | f[n].addr = pat2; | ||
| 162 | n++; | ||
| 163 | } | ||
| 164 | } | ||
| 165 | return (n, f); | ||
| 166 | } | ||
| 167 | |||
| 168 | bscmp(a : File, b : File) : int | ||
| 169 | { | ||
| 170 | return b.seq - a.seq; | ||
| 171 | } | ||
| 172 | |||
| 173 | scmp(a : File, b : File) : int | ||
| 174 | { | ||
| 175 | return a.seq - b.seq; | ||
| 176 | } | ||
| 177 | |||
| 178 | ncmp(a : File, b : File) : int | ||
| 179 | { | ||
| 180 | return strcmp(a.name, b.name); | ||
| 181 | } | ||
| 182 | |||
| 183 | fcmp(a : File, b : File) : int | ||
| 184 | { | ||
| 185 | x : int; | ||
| 186 | |||
| 187 | if (a.name < b.name) | ||
| 188 | return -1; | ||
| 189 | if (a.name > b.name) | ||
| 190 | return 1; | ||
| 191 | x = a.q0 - b.q0; | ||
| 192 | if(x != 0) | ||
| 193 | return x; | ||
| 194 | return a.q1-b.q1; | ||
| 195 | } | ||
| 196 | |||
| 197 | gencmp(a : File, b : File, c : int) : int | ||
| 198 | { | ||
| 199 | if (c == BSCMP) | ||
| 200 | return bscmp(a, b); | ||
| 201 | if (c == SCMP) | ||
| 202 | return scmp(a, b); | ||
| 203 | if (c == NCMP) | ||
| 204 | return ncmp(a, b); | ||
| 205 | if (c == FCMP) | ||
| 206 | return fcmp(a, b); | ||
| 207 | return 0; | ||
| 208 | } | ||
| 209 | |||
| 210 | qsort(a : array of File, n : int, c : int) | ||
| 211 | { | ||
| 212 | i, j : int; | ||
| 213 | t : File; | ||
| 214 | |||
| 215 | while(n > 1) { | ||
| 216 | i = n>>1; | ||
| 217 | t = a[0]; a[0] = a[i]; a[i] = t; | ||
| 218 | i = 0; | ||
| 219 | j = n; | ||
| 220 | for(;;) { | ||
| 221 | do | ||
| 222 | i++; | ||
| 223 | while(i < n && gencmp(a[i], a[0], c) < 0); | ||
| 224 | do | ||
| 225 | j--; | ||
| 226 | while(j > 0 && gencmp(a[j], a[0], c) > 0); | ||
| 227 | if(j < i) | ||
| 228 | break; | ||
| 229 | t = a[i]; a[i] = a[j]; a[j] = t; | ||
| 230 | } | ||
| 231 | t = a[0]; a[0] = a[j]; a[j] = t; | ||
| 232 | n = n-j-1; | ||
| 233 | if(j >= n) { | ||
| 234 | qsort(a, j, c); | ||
| 235 | a = a[j+1:]; | ||
| 236 | } else { | ||
| 237 | qsort(a[j+1:], n, c); | ||
| 238 | n = j; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | prog := "e"; | ||
| 244 | |||
| 245 | main(argv : list of string) | ||
| 246 | { | ||
| 247 | afd, cfd : ref FD; | ||
| 248 | i, id : int; | ||
| 249 | buf : string; | ||
| 250 | nf, n, lines, l0, l1 : int; | ||
| 251 | f, tf : array of File; | ||
| 252 | |||
| 253 | if(len argv < 2){ | ||
| 254 | debug(sys->sprint("usage\n")); | ||
| 255 | fprint(stderr, "usage: %s 'file[:address]' ...\n", prog); | ||
| 256 | exit; | ||
| 257 | } | ||
| 258 | nf = 0; | ||
| 259 | f = nil; | ||
| 260 | for(argv = tl argv; argv != nil; argv = tl argv){ | ||
| 261 | (n, tf) = findfile(hd argv); | ||
| 262 | if(n == 0) | ||
| 263 | errors("no files match pattern", hd argv); | ||
| 264 | oldf := f; | ||
| 265 | f = array[n+nf] of File; | ||
| 266 | if(f == nil) | ||
| 267 | rerror("out of memory"); | ||
| 268 | if (oldf != nil) { | ||
| 269 | f[0:] = oldf[0:nf]; | ||
| 270 | oldf = nil; | ||
| 271 | } | ||
| 272 | f[nf:] = tf[0:n]; | ||
| 273 | nf += n; | ||
| 274 | tf = nil; | ||
| 275 | } | ||
| 276 | debug(sys->sprint("nf=%d\n", nf)); | ||
| 277 | # convert to character positions | ||
| 278 | for(i=0; i<nf; i++){ | ||
| 279 | id = f[i].id; | ||
| 280 | buf = sprint("/mnt/acme/%d/addr", id); | ||
| 281 | # afd = open(buf, ORDWR); | ||
| 282 | # if(afd == nil) | ||
| 283 | # rerror(buf); | ||
| 284 | buf = sprint("/mnt/acme/%d/ctl", id); | ||
| 285 | # cfd = open(buf, ORDWR); | ||
| 286 | # if(cfd == nil) | ||
| 287 | # rerror(buf); | ||
| 288 | if(0 && write(cfd, array of byte "addr=dot\n", 9) != 9) | ||
| 289 | rerror("setting address to dot"); | ||
| 290 | ab := array of byte f[i].addr; | ||
| 291 | if(0 && write(afd, ab, len ab) != len ab){ | ||
| 292 | fprint(stderr, "%s: %s:%s is invalid address\n", prog, f[i].name, f[i].addr); | ||
| 293 | f[i].ok = 0; | ||
| 294 | afd = nil; | ||
| 295 | cfd = nil; | ||
| 296 | continue; | ||
| 297 | } | ||
| 298 | # seek(afd, 0, 0); | ||
| 299 | ab = array[24] of byte; | ||
| 300 | if(0 && read(afd, ab, len ab) != 2*12) | ||
| 301 | rerror("reading address"); | ||
| 302 | afd = nil; | ||
| 303 | cfd = nil; | ||
| 304 | # buf = string ab; | ||
| 305 | ab = nil; | ||
| 306 | f[i].q0 = 0; # int buf; | ||
| 307 | f[i].q1 = 5; # int buf[12:]; | ||
| 308 | f[i].ok = 1; | ||
| 309 | debug(sys->sprint("q0=%d q1=%d\n", f[i].q0, f[i].q1)); | ||
| 310 | } | ||
| 311 | |||
| 312 | # sort | ||
| 313 | # qsort(f, nf, FCMP); | ||
| 314 | |||
| 315 | |||
| 316 | for(i=0; i<nf; i++){ | ||
| 317 | if(f[i].ok) | ||
| 318 | { | ||
| 319 | if(f[i].q1 > f[i].q0) | ||
| 320 | fprint(stdout, "%s:#%d,#%d\n", f[i].name, f[i].q0, f[i].q1); | ||
| 321 | else | ||
| 322 | fprint(stdout, "%s:#%d\n", f[i].name, f[i].q0); | ||
| 323 | } | ||
| 324 | } | ||
| 325 | debug("e exiting\n"); | ||
| 326 | exit; | ||
| 327 | } | ||
| @@ -0,0 +1,5 @@ | |||
| 1 | Mail /mail/box/$user/stored | ||
| 2 | |||
| 3 | Mailpop3 | ||
| 4 | mkbox /mail/box/$user/new_box | ||
| 5 | mail -'x' someaddress | ||
| @@ -0,0 +1,25 @@ | |||
| 1 | implement Mkbox; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | |||
| 6 | sys : Sys; | ||
| 7 | |||
| 8 | FD : import sys; | ||
| 9 | |||
| 10 | Mkbox : module { | ||
| 11 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 12 | }; | ||
| 13 | |||
| 14 | init(nil : ref Draw->Context, argl : list of string) | ||
| 15 | { | ||
| 16 | sys = load Sys Sys->PATH; | ||
| 17 | for (argl = tl argl; argl != nil; argl = tl argl) { | ||
| 18 | nm := hd argl; | ||
| 19 | (ok, dir) := sys->stat(nm); | ||
| 20 | if (ok < 0) { | ||
| 21 | fd := sys->create(nm, Sys->OREAD, 8r600); | ||
| 22 | fd = nil; | ||
| 23 | } | ||
| 24 | } | ||
| 25 | } | ||
| @@ -0,0 +1,34 @@ | |||
| 1 | <../../../../mkconfig | ||
| 2 | |||
| 3 | BIN=$ROOT/acme/mail | ||
| 4 | |||
| 5 | DIRS=\ | ||
| 6 | src\ | ||
| 7 | |||
| 8 | TARG=\ | ||
| 9 | guide\ | ||
| 10 | readme\ | ||
| 11 | mkbox.dis\ | ||
| 12 | |||
| 13 | MODULES=\ | ||
| 14 | |||
| 15 | SYSMODULES=\ | ||
| 16 | sys.m\ | ||
| 17 | draw.m\ | ||
| 18 | |||
| 19 | BINTARG=${TARG:%=$BIN/%} | ||
| 20 | |||
| 21 | DISBIN=$ROOT/acme/mail | ||
| 22 | |||
| 23 | all:V: $TARG | ||
| 24 | |||
| 25 | install:V: $BINTARG | ||
| 26 | |||
| 27 | $BIN/guide : guide | ||
| 28 | rm -f $BIN/guide && cp guide $BIN/guide | ||
| 29 | |||
| 30 | $BIN/readme : readme | ||
| 31 | rm -f $BIN/readme && cp readme $BIN/readme | ||
| 32 | |||
| 33 | <$ROOT/mkfiles/mkdis | ||
| 34 | <$ROOT/mkfiles/mksubdirs | ||
| @@ -0,0 +1,29 @@ | |||
| 1 | Mail is the single program in this directory. Its argument specifies | ||
| 2 | the mail box to read, default /mail/box/$user/mbox. | ||
| 3 | For example, running | ||
| 4 | Mail /mail/box/$user/stored | ||
| 5 | (a line in the guide file) looks at saved mail. | ||
| 6 | |||
| 7 | Mail maintains a window containing headers for all the | ||
| 8 | messages in the mailbox and monitors the mailbox for new messages. | ||
| 9 | Using button 3 to indicate a message number opens | ||
| 10 | a window on that message. commands in the mailbox window are | ||
| 11 | Put Write the mailbox back to the file (never done automatically) | ||
| 12 | Mail Make a new message window ready to mail someone. | ||
| 13 | Takes argument names analogously to acme's New. | ||
| 14 | Del Exit Mail, after checking that mailbox isn't modified. | ||
| 15 | New messages appear at the top of the window and are highlighted upon arrival. | ||
| 16 | (The messages are numbered oldest to newest, the opposite of regular mail.) | ||
| 17 | |||
| 18 | Message windows have a simple format: the first line, up to the first tab or newline, | ||
| 19 | holds the sender or, when sending, the addressee. Edit the line to change who the | ||
| 20 | message goes to. Message windows contain the commands | ||
| 21 | Reply Make a new window to compose a reply to this message | ||
| 22 | Delmesg Delete the message from the screen and from the mailbox | ||
| 23 | Del Delete the window, leaving the message in the mailbox | ||
| 24 | Post Send the message to the addressee | ||
| 25 | Save Save to the named mailbox, default/mail/box/$user/stored | ||
| 26 | Save takes a full file name; if that name has no slashes, the file is taken | ||
| 27 | to be in /mail/box/$user and must already exist. Use mkbox in the guide to | ||
| 28 | create target mailboxes in /mail/box/$user. | ||
| 29 | Reply and mail windows contain an obvious subset of the commands. | ||
| @@ -0,0 +1,1715 @@ | |||
| 1 | implement mail; | ||
| 2 | |||
| 3 | include "sys.m"; | ||
| 4 | include "draw.m"; | ||
| 5 | include "bufio.m"; | ||
| 6 | include "daytime.m"; | ||
| 7 | include "sh.m"; | ||
| 8 | |||
| 9 | mail : module { | ||
| 10 | init : fn(ctxt : ref Draw->Context, argl : list of string); | ||
| 11 | }; | ||
| 12 | |||
| 13 | sys : Sys; | ||
| 14 | bufio : Bufio; | ||
| 15 | daytime : Daytime; | ||
| 16 | |||
| 17 | OREAD, OWRITE, ORDWR, NEWFD, FORKFD, FORKENV, NEWPGRP, UTFmax : import Sys; | ||
| 18 | FD, Dir : import sys; | ||
| 19 | fprint, sprint, sleep, create, open, read, write, remove, stat, fstat, fwstat, fildes, pctl, pipe, dup, byte2char : import sys; | ||
| 20 | Context : import Draw; | ||
| 21 | EOF : import Bufio; | ||
| 22 | Iobuf : import bufio; | ||
| 23 | time : import daytime; | ||
| 24 | |||
| 25 | DIRLEN : con 116; | ||
| 26 | PNPROC, PNGROUP : con iota; | ||
| 27 | False : con 0; | ||
| 28 | True : con 1; | ||
| 29 | EVENTSIZE : con 256; | ||
| 30 | Runeself : con 16r80; | ||
| 31 | OCEXEC : con 0; | ||
| 32 | CHEXCL : con 0; # 16r20000000; # for the moment | ||
| 33 | CHAPPEND : con 0; # 16r40000000; | ||
| 34 | |||
| 35 | MAILDIR : con "/mail"; | ||
| 36 | |||
| 37 | Win : adt { | ||
| 38 | winid : int; | ||
| 39 | addr : ref FD; | ||
| 40 | body : ref Iobuf; | ||
| 41 | ctl : ref FD; | ||
| 42 | data : ref FD; | ||
| 43 | event : ref FD; | ||
| 44 | buf : array of byte; | ||
| 45 | bufp : int; | ||
| 46 | nbuf : int; | ||
| 47 | |||
| 48 | wnew : fn() : ref Win; | ||
| 49 | wwritebody : fn(w : self ref Win, s : string); | ||
| 50 | wread : fn(w : self ref Win, m : int, n : int) : string; | ||
| 51 | wclean : fn(w : self ref Win); | ||
| 52 | wname : fn(w : self ref Win, s : string); | ||
| 53 | wdormant : fn(w : self ref Win); | ||
| 54 | wevent : fn(w : self ref Win, e : ref Event); | ||
| 55 | wshow : fn(w : self ref Win); | ||
| 56 | wtagwrite : fn(w : self ref Win, s : string); | ||
| 57 | wwriteevent : fn(w : self ref Win, e : ref Event); | ||
| 58 | wslave : fn(w : self ref Win, c : chan of Event); | ||
| 59 | wreplace : fn(w : self ref Win, s : string, t : string); | ||
| 60 | wselect : fn(w : self ref Win, s : string); | ||
| 61 | wsetdump : fn(w : self ref Win, s : string, t : string); | ||
| 62 | wdel : fn(w : self ref Win, n : int) : int; | ||
| 63 | wreadall : fn(w : self ref Win) : string; | ||
| 64 | |||
| 65 | ctlwrite : fn(w : self ref Win, s : string); | ||
| 66 | getec : fn(w : self ref Win) : int; | ||
| 67 | geten : fn(w : self ref Win) : int; | ||
| 68 | geter : fn(w : self ref Win, s : array of byte) : (int, int); | ||
| 69 | openfile : fn(w : self ref Win, s : string) : ref FD; | ||
| 70 | openbody : fn(w : self ref Win, n : int); | ||
| 71 | }; | ||
| 72 | |||
| 73 | Mesg : adt { | ||
| 74 | w : ref Win; | ||
| 75 | id : int; | ||
| 76 | hdr : string; | ||
| 77 | realhdr : string; | ||
| 78 | replyto : string; | ||
| 79 | text : string; | ||
| 80 | subj : string; | ||
| 81 | next : cyclic ref Mesg; | ||
| 82 | lline1 : int; | ||
| 83 | box : cyclic ref Box; | ||
| 84 | isopen : int; | ||
| 85 | posted : int; | ||
| 86 | |||
| 87 | read : fn(b : ref Box) : ref Mesg; | ||
| 88 | open : fn(m : self ref Mesg); | ||
| 89 | slave : fn(m : self ref Mesg); | ||
| 90 | free : fn(m : self ref Mesg); | ||
| 91 | save : fn(m : self ref Mesg, s : string); | ||
| 92 | mkreply : fn(m : self ref Mesg); | ||
| 93 | mkmail : fn(b : ref Box, s : string); | ||
| 94 | putpost : fn(m : self ref Mesg, e : ref Event); | ||
| 95 | |||
| 96 | command : fn(m : self ref Mesg, s : string) : int; | ||
| 97 | send : fn(m : self ref Mesg); | ||
| 98 | }; | ||
| 99 | |||
| 100 | Box : adt { | ||
| 101 | w : ref Win; | ||
| 102 | nm : int; | ||
| 103 | readonly : int; | ||
| 104 | m : cyclic ref Mesg; | ||
| 105 | file : string; | ||
| 106 | io : ref Iobuf; | ||
| 107 | clean : int; | ||
| 108 | leng : big; | ||
| 109 | cdel : chan of ref Mesg; | ||
| 110 | cevent : chan of Event; | ||
| 111 | cmore : chan of int; | ||
| 112 | |||
| 113 | line : string; | ||
| 114 | peekline : string; | ||
| 115 | |||
| 116 | read : fn(s : string, n : int) : ref Box; | ||
| 117 | readmore : fn(b : self ref Box); | ||
| 118 | readline : fn(b : self ref Box) : string; | ||
| 119 | unreadline : fn(b : self ref Box); | ||
| 120 | slave : fn(b : self ref Box); | ||
| 121 | mopen : fn(b : self ref Box, n : int); | ||
| 122 | rewrite : fn(b : self ref Box); | ||
| 123 | mdel : fn(b : self ref Box, m : ref Mesg); | ||
| 124 | event : fn(b : self ref Box, e : ref Event); | ||
| 125 | |||
| 126 | command : fn(b : self ref Box, s : string) : int; | ||
| 127 | }; | ||
| 128 | |||
| 129 | Event : adt { | ||
| 130 | c1 : int; | ||
| 131 | c2 : int; | ||
| 132 | q0 : int; | ||
| 133 | q1 : int; | ||
| 134 | flag : int; | ||
| 135 | nb : int; | ||
| 136 | nr : int; | ||
| 137 | b : array of byte; | ||
| 138 | r : array of int; | ||
| 139 | }; | ||
| 140 | |||
| 141 | Lock : adt { | ||
| 142 | cnt : int; | ||
| 143 | chann : chan of int; | ||
| 144 | |||
| 145 | init : fn() : ref Lock; | ||
| 146 | lock : fn(l : self ref Lock); | ||
| 147 | unlock : fn(l : self ref Lock); | ||
| 148 | }; | ||
| 149 | |||
| 150 | Ref : adt { | ||
| 151 | l : ref Lock; | ||
| 152 | cnt : int; | ||
| 153 | |||
| 154 | init : fn() : ref Ref; | ||
| 155 | inc : fn(r : self ref Ref) : int; | ||
| 156 | }; | ||
| 157 | |||
| 158 | mbox : ref Box; | ||
| 159 | mboxfile : string; | ||
| 160 | usermboxfile : string; | ||
| 161 | usermboxdir : string; | ||
| 162 | lockfile : string; | ||
| 163 | user : string; | ||
| 164 | date : string; | ||
| 165 | mailctxt : ref Context; | ||
| 166 | stdout, stderr : ref FD; | ||
| 167 | |||
| 168 | killing : int = 0; | ||
| 169 | |||
| 170 | init(ctxt : ref Context, argl : list of string) | ||
| 171 | { | ||
| 172 | mailctxt = ctxt; | ||
| 173 | sys = load Sys Sys->PATH; | ||
| 174 | bufio = load Bufio Bufio->PATH; | ||
| 175 | daytime = load Daytime Daytime->PATH; | ||
| 176 | stdout = fildes(1); | ||
| 177 | stderr = fildes(2); | ||
| 178 | main(argl); | ||
| 179 | } | ||
| 180 | |||
| 181 | dlock : ref Lock; | ||
| 182 | dfd : ref Sys->FD; | ||
| 183 | |||
| 184 | debug(s : string) | ||
| 185 | { | ||
| 186 | if (dfd == nil) { | ||
| 187 | dfd = sys->create("/usr/jrf/acme/debugmail", Sys->OWRITE, 8r600); | ||
| 188 | dlock = Lock.init(); | ||
| 189 | } | ||
| 190 | if (dfd == nil) | ||
| 191 | return; | ||
| 192 | dlock.lock(); | ||
| 193 | sys->fprint(dfd, "%s", s); | ||
| 194 | dlock.unlock(); | ||
| 195 | } | ||
| 196 | |||
| 197 | postnote(t : int, pid : int, note : string) : int | ||
| 198 | { | ||
| 199 | fd := open("#p/" + string pid + "/ctl", OWRITE); | ||
| 200 | if (fd == nil) | ||
| 201 | return -1; | ||
| 202 | if (t == PNGROUP) | ||
| 203 | note += "grp"; | ||
| 204 | fprint(fd, "%s", note); | ||
| 205 | fd = nil; | ||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | exec(cmd : string, argl : list of string) | ||
| 210 | { | ||
| 211 | file := cmd; | ||
| 212 | if(len file<4 || file[len file-4:]!=".dis") | ||
| 213 | file += ".dis"; | ||
| 214 | |||
| 215 | c := load Command file; | ||
| 216 | if(c == nil) { | ||
| 217 | err := sprint("%r"); | ||
| 218 | if(file[0]!='/' && file[0:2]!="./"){ | ||
| 219 | c = load Command "/dis/"+file; | ||
| 220 | if(c == nil) | ||
| 221 | err = sprint("%r"); | ||
| 222 | } | ||
| 223 | if(c == nil){ | ||
| 224 | fprint(stderr, "%s: %s\n", cmd, err); | ||
| 225 | return; | ||
| 226 | } | ||
| 227 | } | ||
| 228 | c->init(mailctxt, argl); | ||
| 229 | } | ||
| 230 | |||
| 231 | swrite(fd : ref FD, s : string) : int | ||
| 232 | { | ||
| 233 | ab := array of byte s; | ||
| 234 | m := len ab; | ||
| 235 | p := write(fd, ab, m); | ||
| 236 | if (p == m) | ||
| 237 | return len s; | ||
| 238 | if (p <= 0) | ||
| 239 | return p; | ||
| 240 | return 0; | ||
| 241 | } | ||
| 242 | |||
| 243 | strchr(s : string, c : int) : int | ||
| 244 | { | ||
| 245 | for (i := 0; i < len s; i++) | ||
| 246 | if (s[i] == c) | ||
| 247 | return i; | ||
| 248 | return -1; | ||
| 249 | } | ||
| 250 | |||
| 251 | strrchr(s : string, c : int) : int | ||
| 252 | { | ||
| 253 | for (i := len s - 1; i >= 0; i--) | ||
| 254 | if (s[i] == c) | ||
| 255 | return i; | ||
| 256 | return -1; | ||
| 257 | } | ||
| 258 | |||
| 259 | strtoi(s : string) : (int, int) | ||
| 260 | { | ||
| 261 | m := 0; | ||
| 262 | neg := 0; | ||
| 263 | t := 0; | ||
| 264 | ls := len s; | ||
| 265 | while (t < ls && (s[t] == ' ' || s[t] == '\t')) | ||
| 266 | t++; | ||
| 267 | if (t < ls && s[t] == '+') | ||
| 268 | t++; | ||
| 269 | else if (t < ls && s[t] == '-') { | ||
| 270 | neg = 1; | ||
| 271 | t++; | ||
| 272 | } | ||
| 273 | while (t < ls && (s[t] >= '0' && s[t] <= '9')) { | ||
| 274 | m = 10*m + s[t]-'0'; | ||
| 275 | t++; | ||
| 276 | } | ||
| 277 | if (neg) | ||
| 278 | m = -m; | ||
| 279 | return (m, t); | ||
| 280 | } | ||
| 281 | |||
| 282 | access(s : string) : int | ||
| 283 | { | ||
| 284 | fd := open(s, 0); | ||
| 285 | if (fd == nil) | ||
| 286 | return -1; | ||
| 287 | fd = nil; | ||
| 288 | return 0; | ||
| 289 | } | ||
| 290 | |||
| 291 | newevent() : ref Event | ||
| 292 | { | ||
| 293 | e := ref Event; | ||
| 294 | e.b = array[EVENTSIZE*UTFmax+1] of byte; | ||
| 295 | e.r = array[EVENTSIZE+1] of int; | ||
| 296 | return e; | ||
| 297 | } | ||
| 298 | |||
| 299 | newmesg() : ref Mesg | ||
| 300 | { | ||
| 301 | m := ref Mesg; | ||
| 302 | m.id = m.lline1 = m.isopen = m.posted = 0; | ||
| 303 | return m; | ||
| 304 | } | ||
| 305 | |||
| 306 | lc, uc : chan of ref Lock; | ||
| 307 | |||
| 308 | initlock() | ||
| 309 | { | ||
| 310 | lc = chan of ref Lock; | ||
| 311 | uc = chan of ref Lock; | ||
| 312 | spawn lockmgr(); | ||
| 313 | } | ||
| 314 | |||
| 315 | lockmgr() | ||
| 316 | { | ||
| 317 | l : ref Lock; | ||
| 318 | |||
| 319 | for (;;) { | ||
| 320 | alt { | ||
| 321 | l = <- lc => | ||
| 322 | if (l.cnt++ == 0) | ||
| 323 | l.chann <-= 1; | ||
| 324 | l = <- uc => | ||
| 325 | if (--l.cnt > 0) | ||
| 326 | l.chann <-= 1; | ||
| 327 | } | ||
| 328 | } | ||
| 329 | } | ||
| 330 | |||
| 331 | Lock.init() : ref Lock | ||
| 332 | { | ||
| 333 | return ref Lock(0, chan of int); | ||
| 334 | } | ||
| 335 | |||
| 336 | Lock.lock(l : self ref Lock) | ||
| 337 | { | ||
| 338 | lc <-= l; | ||
| 339 | <- l.chann; | ||
| 340 | } | ||
| 341 | |||
| 342 | Lock.unlock(l : self ref Lock) | ||
| 343 | { | ||
| 344 | uc <-= l; | ||
| 345 | } | ||
| 346 | |||
| 347 | Ref.init() : ref Ref | ||
| 348 | { | ||
| 349 | r := ref Ref; | ||
| 350 | r.l = Lock.init(); | ||
| 351 | r.cnt = 0; | ||
| 352 | return r; | ||
| 353 | } | ||
| 354 | |||
| 355 | Ref.inc(r : self ref Ref) : int | ||
| 356 | { | ||
| 357 | r.l.lock(); | ||
| 358 | i := r.cnt; | ||
| 359 | r.cnt++; | ||
| 360 | r.l.unlock(); | ||
| 361 | return i; | ||
| 362 | } | ||
| 363 | |||
| 364 | error(s : string) | ||
| 365 | { | ||
| 366 | if(s != nil) | ||
| 367 | fprint(stderr, "mail: %s\n", s); | ||
| 368 | rmlockfile(); | ||
| 369 | # debug(sprint("error %s\n", s)); | ||
| 370 | postnote(PNGROUP, pctl(0, nil), "kill"); | ||
| 371 | killing = 1; | ||
| 372 | exit; | ||
| 373 | } | ||
| 374 | |||
| 375 | rmlockfile() | ||
| 376 | { | ||
| 377 | if (lockfile != nil) { | ||
| 378 | remove(lockfile); | ||
| 379 | lockfile = nil; | ||
| 380 | } | ||
| 381 | } | ||
| 382 | |||
| 383 | # | ||
| 384 | # try opening a lock file. If it doesn't exist try creating it. | ||
| 385 | # | ||
| 386 | openlockfile(path : string) : ref FD | ||
| 387 | { | ||
| 388 | try : int; | ||
| 389 | fd : ref FD; | ||
| 390 | |||
| 391 | try = 0; | ||
| 392 | for(;;){ | ||
| 393 | # fd = open(path, OWRITE); | ||
| 394 | # if(fd!=nil || ++try>3) | ||
| 395 | # return fd; | ||
| 396 | if(++try > 3) | ||
| 397 | return fd; | ||
| 398 | (ok, d) := stat(path); | ||
| 399 | if(ok >= 0) | ||
| 400 | sleep(1000); | ||
| 401 | else{ | ||
| 402 | fd = create(path, OWRITE, CHEXCL|8r666); | ||
| 403 | if(fd != nil){ | ||
| 404 | (ok, d) = fstat(fd); | ||
| 405 | if(ok >= 0){ | ||
| 406 | d.mode |= CHEXCL|8r666; | ||
| 407 | fwstat(fd, d); | ||
| 408 | } | ||
| 409 | return fd; | ||
| 410 | } | ||
| 411 | break; | ||
| 412 | } | ||
| 413 | } | ||
| 414 | return nil; | ||
| 415 | } | ||
| 416 | |||
| 417 | tryopen(s : string, mode : int) : ref FD | ||
| 418 | { | ||
| 419 | fd : ref FD; | ||
| 420 | try : int; | ||
| 421 | |||
| 422 | for(try=0; try<3; try++){ | ||
| 423 | fd = open(s, mode); | ||
| 424 | if(fd != nil) | ||
| 425 | return fd; | ||
| 426 | sleep(1000); | ||
| 427 | } | ||
| 428 | return nil; | ||
| 429 | } | ||
| 430 | |||
| 431 | run(argv : list of string, c : chan of int, p0 : ref FD) | ||
| 432 | { | ||
| 433 | # pctl(FORKFD|NEWPGRP, nil); # had RFMEM | ||
| 434 | pctl(FORKENV|NEWFD|NEWPGRP, 0::1::2::p0.fd::nil); | ||
| 435 | c <-= pctl(0, nil); | ||
| 436 | dup(p0.fd, 0); | ||
| 437 | p0 = nil; | ||
| 438 | exec(hd argv, argv); | ||
| 439 | exit; | ||
| 440 | } | ||
| 441 | |||
| 442 | getuser() : string | ||
| 443 | { | ||
| 444 | fd := open("/dev/user", OREAD); | ||
| 445 | if(fd == nil) | ||
| 446 | return ""; | ||
| 447 | buf := array[128] of byte; | ||
| 448 | n := read(fd, buf, len buf); | ||
| 449 | if(n < 0) | ||
| 450 | return ""; | ||
| 451 | return string buf[0:n]; | ||
| 452 | } | ||
| 453 | |||
| 454 | main(argv : list of string) | ||
| 455 | { | ||
| 456 | fd : ref FD; | ||
| 457 | readonly : int; | ||
| 458 | buf : string; | ||
| 459 | |||
| 460 | initlock(); | ||
| 461 | initreply(); | ||
| 462 | date = time(); | ||
| 463 | if(date==nil) | ||
| 464 | error("can't get current time"); | ||
| 465 | user = getuser(); | ||
| 466 | if(user == nil) | ||
| 467 | user = "Wile.E.Coyote"; | ||
| 468 | usermboxdir = MAILDIR + "/box/" + user + "/"; | ||
| 469 | usermboxfile = MAILDIR + "/box/" + user + "/mbox"; | ||
| 470 | if(len argv > 1) | ||
| 471 | mboxfile = hd tl argv; | ||
| 472 | else | ||
| 473 | mboxfile = usermboxfile; | ||
| 474 | |||
| 475 | fd = nil; | ||
| 476 | readonly = False; | ||
| 477 | if(mboxfile == usermboxfile){ | ||
| 478 | buf = MAILDIR + "/box/" + user + "/L.reading"; | ||
| 479 | fd = openlockfile(buf); | ||
| 480 | if(fd == nil){ | ||
| 481 | fprint(stderr, "Mail: %s in use; opened read-only\n", mboxfile); | ||
| 482 | readonly = True; | ||
| 483 | } | ||
| 484 | else | ||
| 485 | lockfile = buf; | ||
| 486 | } | ||
| 487 | mbox = mbox.read(mboxfile, readonly); | ||
| 488 | spawn timeslave(fd, mbox, mbox.cmore); | ||
| 489 | mbox.slave(); | ||
| 490 | error(nil); | ||
| 491 | } | ||
| 492 | |||
| 493 | timeslave(rlock : ref FD, b : ref Box, c : chan of int) | ||
| 494 | { | ||
| 495 | buf := array[DIRLEN] of byte; | ||
| 496 | for(;;){ | ||
| 497 | sleep(30*1000); | ||
| 498 | if(rlock != nil && write(rlock, buf, 0)<0) | ||
| 499 | error("can't maintain L.reading: %r"); | ||
| 500 | (ok, d) := stat(mboxfile); | ||
| 501 | if (ok >= 0 && d.length > b.leng) | ||
| 502 | c <-= 0; | ||
| 503 | } | ||
| 504 | } | ||
| 505 | |||
| 506 | Win.wnew() : ref Win | ||
| 507 | { | ||
| 508 | w := ref Win; | ||
| 509 | buf := array[12] of byte; | ||
| 510 | w.ctl = open("/chan/new/ctl", ORDWR); | ||
| 511 | if(w.ctl==nil || read(w.ctl, buf, 12)!=12) | ||
| 512 | error("can't open window ctl file: %r"); | ||
| 513 | w.ctlwrite("noscroll\n"); | ||
| 514 | w.winid = int string buf; | ||
| 515 | w.event = w.openfile("event"); | ||
| 516 | w.addr = nil; # will be opened when needed | ||
| 517 | w.body = nil; | ||
| 518 | w.data = nil; | ||
| 519 | w.bufp = w.nbuf = 0; | ||
| 520 | w.buf = array[512] of byte; | ||
| 521 | return w; | ||
| 522 | } | ||
| 523 | |||
| 524 | Win.openfile(w : self ref Win, f : string) : ref FD | ||
| 525 | { | ||
| 526 | buf := sprint("/chan/%d/%s", w.winid, f); | ||
| 527 | fd := open(buf, ORDWR|OCEXEC); | ||
| 528 | if(fd == nil) | ||
| 529 | error(sprint("can't open window %s file: %r", f)); | ||
| 530 | return fd; | ||
| 531 | } | ||
| 532 | |||
| 533 | Win.openbody(w : self ref Win, mode : int) | ||
| 534 | { | ||
| 535 | buf := sprint("/chan/%d/body", w.winid); | ||
| 536 | w.body = bufio->open(buf, mode|OCEXEC); | ||
| 537 | if(w.body == nil) | ||
| 538 | error("can't open window body file: %r"); | ||
| 539 | } | ||
| 540 | |||
| 541 | Win.wwritebody(w : self ref Win, s : string) | ||
| 542 | { | ||
| 543 | n := len s; | ||
| 544 | if(w.body == nil) | ||
| 545 | w.openbody(OWRITE); | ||
| 546 | if(w.body.puts(s) != n) | ||
| 547 | error("write error to window: %r"); | ||
| 548 | } | ||
| 549 | |||
| 550 | Win.wreplace(w : self ref Win, addr : string, repl : string) | ||
| 551 | { | ||
| 552 | if(w.addr == nil) | ||
| 553 | w.addr = w.openfile("addr"); | ||
| 554 | if(w.data == nil) | ||
| 555 | w.data = w.openfile("data"); | ||
| 556 | if(swrite(w.addr, addr) < 0){ | ||
| 557 | fprint(stderr, "mail: warning: bad address %s:%r\n", addr); | ||
| 558 | return; | ||
| 559 | } | ||
| 560 | if(swrite(w.data, repl) != len repl) | ||
| 561 | error("writing data: %r"); | ||
| 562 | } | ||
| 563 | |||
| 564 | nrunes(s : array of byte, nb : int) : int | ||
| 565 | { | ||
| 566 | i, n : int; | ||
| 567 | |||
| 568 | n = 0; | ||
| 569 | for(i=0; i<nb; n++) { | ||
| 570 | (r, b, ok) := byte2char(s, i); | ||
| 571 | if (!ok) | ||
| 572 | error("help needed in nrunes()"); | ||
| 573 | i += b; | ||
| 574 | } | ||
| 575 | return n; | ||
| 576 | } | ||
| 577 | |||
| 578 | Win.wread(w : self ref Win, q0 : int, q1 : int) : string | ||
| 579 | { | ||
| 580 | m, n, nr : int; | ||
| 581 | s, buf : string; | ||
| 582 | b : array of byte; | ||
| 583 | |||
| 584 | b = array[256] of byte; | ||
| 585 | if(w.addr == nil) | ||
| 586 | w.addr = w.openfile("addr"); | ||
| 587 | if(w.data == nil) | ||
| 588 | w.data = w.openfile("data"); | ||
| 589 | s = nil; | ||
| 590 | m = q0; | ||
| 591 | while(m < q1){ | ||
| 592 | buf = sprint("#%d", m); | ||
| 593 | if(swrite(w.addr, buf) != len buf) | ||
| 594 | error("writing addr: %r"); | ||
| 595 | n = read(w.data, b, len b); | ||
| 596 | if(n <= 0) | ||
| 597 | error("reading data: %r"); | ||
| 598 | nr = nrunes(b, n); | ||
| 599 | while(m+nr >q1){ | ||
| 600 | do; while(n>0 && (int b[--n]&16rC0)==16r80); | ||
| 601 | --nr; | ||
| 602 | } | ||
| 603 | if(n == 0) | ||
| 604 | break; | ||
| 605 | s += string b[0:n]; | ||
| 606 | m += nr; | ||
| 607 | } | ||
| 608 | return s; | ||
| 609 | } | ||
| 610 | |||
| 611 | Win.wshow(w : self ref Win) | ||
| 612 | { | ||
| 613 | w.ctlwrite("show\n"); | ||
| 614 | } | ||
| 615 | |||
| 616 | Win.wsetdump(w : self ref Win, dir : string, cmd : string) | ||
| 617 | { | ||
| 618 | t : string; | ||
| 619 | |||
| 620 | if(dir != nil){ | ||
| 621 | t = "dumpdir " + dir + "\n"; | ||
| 622 | w.ctlwrite(t); | ||
| 623 | t = nil; | ||
| 624 | } | ||
| 625 | if(cmd != nil){ | ||
| 626 | t = "dump " + cmd + "\n"; | ||
| 627 | w.ctlwrite(t); | ||
| 628 | t = nil; | ||
| 629 | } | ||
| 630 | } | ||
| 631 | |||
| 632 | Win.wselect(w : self ref Win, addr : string) | ||
| 633 | { | ||
| 634 | if(w.addr == nil) | ||
| 635 | w.addr = w.openfile("addr"); | ||
| 636 | if(swrite(w.addr, addr) < 0) | ||
| 637 | error("writing addr"); | ||
| 638 | w.ctlwrite("dot=addr\n"); | ||
| 639 | } | ||
| 640 | |||
| 641 | Win.wtagwrite(w : self ref Win, s : string) | ||
| 642 | { | ||
| 643 | fd : ref FD; | ||
| 644 | |||
| 645 | fd = w.openfile("tag"); | ||
| 646 | if(swrite(fd, s) != len s) | ||
| 647 | error("tag write: %r"); | ||
| 648 | fd = nil; | ||
| 649 | } | ||
| 650 | |||
| 651 | Win.ctlwrite(w : self ref Win, s : string) | ||
| 652 | { | ||
| 653 | if(swrite(w.ctl, s) != len s) | ||
| 654 | error("write error to ctl file: %r"); | ||
| 655 | } | ||
| 656 | |||
| 657 | Win.wdel(w : self ref Win, sure : int) : int | ||
| 658 | { | ||
| 659 | if (w == nil) | ||
| 660 | return False; | ||
| 661 | if(sure) | ||
| 662 | swrite(w.ctl, "delete\n"); | ||
| 663 | else if(swrite(w.ctl, "del\n") != 4) | ||
| 664 | return False; | ||
| 665 | w.wdormant(); | ||
| 666 | w.ctl = nil; | ||
| 667 | w.event = nil; | ||
| 668 | return True; | ||
| 669 | } | ||
| 670 | |||
| 671 | Win.wname(w : self ref Win, s : string) | ||
| 672 | { | ||
| 673 | w.ctlwrite("name " + s + "\n"); | ||
| 674 | } | ||
| 675 | |||
| 676 | Win.wclean(w : self ref Win) | ||
| 677 | { | ||
| 678 | if(w.body != nil) | ||
| 679 | w.body.flush(); | ||
| 680 | w.ctlwrite("clean\n"); | ||
| 681 | } | ||
| 682 | |||
| 683 | Win.wdormant(w : self ref Win) | ||
| 684 | { | ||
| 685 | w.addr = nil; | ||
| 686 | if(w.body != nil){ | ||
| 687 | w.body.close(); | ||
| 688 | w.body = nil; | ||
| 689 | } | ||
| 690 | w.data = nil; | ||
| 691 | } | ||
| 692 | |||
| 693 | Win.getec(w : self ref Win) : int | ||
| 694 | { | ||
| 695 | if(w.nbuf == 0){ | ||
| 696 | w.nbuf = read(w.event, w.buf, len w.buf); | ||
| 697 | if(w.nbuf <= 0 && !killing) { | ||
| 698 | error("event read error: %r"); | ||
| 699 | } | ||
| 700 | w.bufp = 0; | ||
| 701 | } | ||
| 702 | w.nbuf--; | ||
| 703 | return int w.buf[w.bufp++]; | ||
| 704 | } | ||
| 705 | |||
| 706 | Win.geten(w : self ref Win) : int | ||
| 707 | { | ||
| 708 | n, c : int; | ||
| 709 | |||
| 710 | n = 0; | ||
| 711 | while('0'<=(c=w.getec()) && c<='9') | ||
| 712 | n = n*10+(c-'0'); | ||
| 713 | if(c != ' ') | ||
| 714 | error("event number syntax"); | ||
| 715 | return n; | ||
| 716 | } | ||
| 717 | |||
| 718 | Win.geter(w : self ref Win, buf : array of byte) : (int, int) | ||
| 719 | { | ||
| 720 | r, m, n, ok : int; | ||
| 721 | |||
| 722 | r = w.getec(); | ||
| 723 | buf[0] = byte r; | ||
| 724 | n = 1; | ||
| 725 | if(r >= Runeself) { | ||
| 726 | for (;;) { | ||
| 727 | (r, m, ok) = byte2char(buf[0:n], 0); | ||
| 728 | if (m > 0) | ||
| 729 | return (r, n); | ||
| 730 | buf[n++] = byte w.getec(); | ||
| 731 | } | ||
| 732 | } | ||
| 733 | return (r, n); | ||
| 734 | } | ||
| 735 | |||
| 736 | Win.wevent(w : self ref Win, e : ref Event) | ||
| 737 | { | ||
| 738 | i, nb : int; | ||
| 739 | |||
| 740 | e.c1 = w.getec(); | ||
| 741 | e.c2 = w.getec(); | ||
| 742 | e.q0 = w.geten(); | ||
| 743 | e.q1 = w.geten(); | ||
| 744 | e.flag = w.geten(); | ||
| 745 | e.nr = w.geten(); | ||
| 746 | if(e.nr > EVENTSIZE) | ||
| 747 | error("event string too long"); | ||
| 748 | e.nb = 0; | ||
| 749 | for(i=0; i<e.nr; i++){ | ||
| 750 | (e.r[i], nb) = w.geter(e.b[e.nb:]); | ||
| 751 | e.nb += nb; | ||
| 752 | } | ||
| 753 | e.r[e.nr] = 0; | ||
| 754 | e.b[e.nb] = byte 0; | ||
| 755 | c := w.getec(); | ||
| 756 | if(c != '\n') | ||
| 757 | error("event syntax 2"); | ||
| 758 | } | ||
| 759 | |||
| 760 | Win.wslave(w : self ref Win, ce : chan of Event) | ||
| 761 | { | ||
| 762 | e : ref Event; | ||
| 763 | |||
| 764 | e = newevent(); | ||
| 765 | for(;;){ | ||
| 766 | w.wevent(e); | ||
| 767 | ce <-= *e; | ||
| 768 | } | ||
| 769 | } | ||
| 770 | |||
| 771 | Win.wwriteevent(w : self ref Win, e : ref Event) | ||
| 772 | { | ||
| 773 | fprint(w.event, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1); | ||
| 774 | } | ||
| 775 | |||
| 776 | Win.wreadall(w : self ref Win) : string | ||
| 777 | { | ||
| 778 | s, t : string; | ||
| 779 | |||
| 780 | if(w.body != nil) | ||
| 781 | w.body.close(); | ||
| 782 | w.openbody(OREAD); | ||
| 783 | s = nil; | ||
| 784 | while ((t = w.body.gets('\n')) != nil) | ||
| 785 | s += t; | ||
| 786 | w.body.close(); | ||
| 787 | w.body = nil; | ||
| 788 | return s; | ||
| 789 | } | ||
| 790 | |||
| 791 | ignored : int; | ||
| 792 | |||
| 793 | None,Unknown,Ignore,CC,From,ReplyTo,Sender,Subject,Re,To, Date : con iota; | ||
| 794 | NHeaders : con 200; | ||
| 795 | |||
| 796 | Hdrs : adt { | ||
| 797 | name : string; | ||
| 798 | typex : int; | ||
| 799 | }; | ||
| 800 | |||
| 801 | |||
| 802 | hdrs := array[NHeaders+1] of { | ||
| 803 | Hdrs ( "CC:", CC ), | ||
| 804 | Hdrs ( "From:", From ), | ||
| 805 | Hdrs ( "Reply-To:", ReplyTo ), | ||
| 806 | Hdrs ( "Sender:", Sender ), | ||
| 807 | Hdrs ( "Subject:", Subject ), | ||
| 808 | Hdrs ( "Re:", Re ), | ||
| 809 | Hdrs ( "To:", To ), | ||
| 810 | Hdrs ( "Date:", Date), | ||
| 811 | * => Hdrs ( "", 0 ), | ||
| 812 | }; | ||
| 813 | |||
| 814 | StRnCmP(s : string, t : string, n : int) : int | ||
| 815 | { | ||
| 816 | c, d, i, j : int; | ||
| 817 | |||
| 818 | i = j = 0; | ||
| 819 | if (len s < n || len t < n) | ||
| 820 | return -1; | ||
| 821 | while(n > 0){ | ||
| 822 | c = s[i++]; | ||
| 823 | d = t[j++]; | ||
| 824 | --n; | ||
| 825 | if(c != d){ | ||
| 826 | if('a'<=c && c<='z') | ||
| 827 | c -= 'a'-'A'; | ||
| 828 | if('a'<=d && d<='z') | ||
| 829 | d -= 'a'-'A'; | ||
| 830 | if(c != d) | ||
| 831 | return c-d; | ||
| 832 | } | ||
| 833 | } | ||
| 834 | return 0; | ||
| 835 | } | ||
| 836 | |||
| 837 | ignore() | ||
| 838 | { | ||
| 839 | b : ref Iobuf; | ||
| 840 | s : string; | ||
| 841 | i : int; | ||
| 842 | |||
| 843 | ignored = True; | ||
| 844 | b = bufio->open(MAILDIR + "/lib/ignore", OREAD); | ||
| 845 | if(b == nil) | ||
| 846 | return; | ||
| 847 | for(i=0; hdrs[i].name != nil; i++) | ||
| 848 | ; | ||
| 849 | while((s = b.gets('\n')) != nil){ | ||
| 850 | s = s[0:len s - 1]; | ||
| 851 | hdrs[i].name = s; | ||
| 852 | hdrs[i].typex = Ignore; | ||
| 853 | if(++i >= NHeaders){ | ||
| 854 | fprint(stderr, "%s/lib/ignore has more than %d headers\n", MAILDIR, NHeaders); | ||
| 855 | break; | ||
| 856 | } | ||
| 857 | } | ||
| 858 | b.close(); | ||
| 859 | } | ||
| 860 | |||
| 861 | readhdr(b : ref Box) : (string, int) | ||
| 862 | { | ||
| 863 | i, j, n, m, typex : int; | ||
| 864 | s, t : string; | ||
| 865 | |||
| 866 | { | ||
| 867 | if(!ignored) | ||
| 868 | ignore(); | ||
| 869 | s = b.readline(); | ||
| 870 | n = len s; | ||
| 871 | if(n <= 0) | ||
| 872 | raise("e"); | ||
| 873 | for(i=0; i<n; i++){ | ||
| 874 | j = s[i]; | ||
| 875 | if(i>0 && j == ':') | ||
| 876 | break; | ||
| 877 | if(j<'!' || '~'<j){ | ||
| 878 | b.unreadline(); | ||
| 879 | raise("e"); | ||
| 880 | } | ||
| 881 | } | ||
| 882 | typex = Unknown; | ||
| 883 | for(i=0; hdrs[i].name != nil; i++){ | ||
| 884 | j = len hdrs[i].name; | ||
| 885 | if(StRnCmP(hdrs[i].name, s, j) == 0){ | ||
| 886 | typex = hdrs[i].typex; | ||
| 887 | break; | ||
| 888 | } | ||
| 889 | } | ||
| 890 | # scan for multiple sublines | ||
| 891 | for(;;){ | ||
| 892 | t = b.readline(); | ||
| 893 | m = len t; | ||
| 894 | if(m<=0 || (t[0]!=' ' && t[0]!='\t')){ | ||
| 895 | b.unreadline(); | ||
| 896 | break; | ||
| 897 | } | ||
| 898 | # absorb | ||
| 899 | s += t; | ||
| 900 | } | ||
| 901 | return(s, typex); | ||
| 902 | } | ||
| 903 | exception{ | ||
| 904 | "*" => | ||
| 905 | return (nil, None); | ||
| 906 | } | ||
| 907 | } | ||
| 908 | |||
| 909 | Mesg.read(b : ref Box) : ref Mesg | ||
| 910 | { | ||
| 911 | m : ref Mesg; | ||
| 912 | s : string; | ||
| 913 | n, typex : int; | ||
| 914 | |||
| 915 | s = b.readline(); | ||
| 916 | n = len s; | ||
| 917 | if(n <= 0) | ||
| 918 | return nil; | ||
| 919 | |||
| 920 | { | ||
| 921 | if(n < 5 || s[0:5] !="From ") | ||
| 922 | raise("e"); | ||
| 923 | m = newmesg(); | ||
| 924 | m.realhdr = s; | ||
| 925 | # toss 'From ' | ||
| 926 | s = s[5:]; | ||
| 927 | n -= 5; | ||
| 928 | # toss spaces/tabs | ||
| 929 | while (n > 0 && (s[0] == ' ' || s[0] == '\t')) { | ||
| 930 | s = s[1:]; | ||
| 931 | n--; | ||
| 932 | } | ||
| 933 | m.hdr = s; | ||
| 934 | # convert first blank to tab | ||
| 935 | s0 := strchr(m.hdr, ' '); | ||
| 936 | if(s0 >= 0){ | ||
| 937 | m.hdr[s0] = '\t'; | ||
| 938 | # drop trailing seconds, time zone, and year if match local year | ||
| 939 | t := n-6; | ||
| 940 | if(t <= 0) | ||
| 941 | raise("e"); | ||
| 942 | if(m.hdr[t:n-1] == date[23:]){ | ||
| 943 | m.hdr = m.hdr[0:t] + "\n"; # drop year for sure | ||
| 944 | t = -1; | ||
| 945 | s1 := strchr(m.hdr[s0:], ':'); | ||
| 946 | if(s1 >= 0) | ||
| 947 | t = strchr(m.hdr[s0+s1+1:], ':'); | ||
| 948 | if(t >= 0) # drop seconds and time zone | ||
| 949 | m.hdr = m.hdr[0:s0+s1+t+1] + "\n"; | ||
| 950 | else{ # drop time zone | ||
| 951 | t = strchr(m.hdr[s0+s1+1:], ' '); | ||
| 952 | if(t >= 0) | ||
| 953 | m.hdr = m.hdr[0:s0+s1+t+1] + "\n"; | ||
| 954 | } | ||
| 955 | n = len m.hdr; | ||
| 956 | } | ||
| 957 | } | ||
| 958 | m.lline1 = n; | ||
| 959 | m.text = nil; | ||
| 960 | # read header | ||
| 961 | loop: | ||
| 962 | for(;;){ | ||
| 963 | (s, typex) = readhdr(b); | ||
| 964 | case(typex){ | ||
| 965 | None => | ||
| 966 | break loop; | ||
| 967 | ReplyTo => | ||
| 968 | m.replyto = s[9:]; | ||
| 969 | break; | ||
| 970 | From => | ||
| 971 | if(m.replyto == nil) | ||
| 972 | m.replyto = s[5:]; | ||
| 973 | break; | ||
| 974 | Subject => | ||
| 975 | m.subj = s[8:]; | ||
| 976 | break; | ||
| 977 | Re => | ||
| 978 | m.subj = s[3:]; | ||
| 979 | break; | ||
| 980 | Date => | ||
| 981 | break; | ||
| 982 | } | ||
| 983 | m.realhdr += s; | ||
| 984 | if(typex != Ignore) | ||
| 985 | m.hdr += s; | ||
| 986 | } | ||
| 987 | # read body | ||
| 988 | for(;;){ | ||
| 989 | s = b.readline(); | ||
| 990 | n = len s; | ||
| 991 | if(n <= 0) | ||
| 992 | break; | ||
| 993 | if(len s >= 5 && s[0:5] == "From "){ | ||
| 994 | b.unreadline(); | ||
| 995 | break; | ||
| 996 | } | ||
| 997 | m.text += s; | ||
| 998 | } | ||
| 999 | # remove trailing "morF\n" | ||
| 1000 | l := len m.text; | ||
| 1001 | if(l>6 && m.text[l-6:] == "\nmorF\n") | ||
| 1002 | m.text = m.text[0:l-5]; | ||
| 1003 | m.box = b; | ||
| 1004 | return m; | ||
| 1005 | } | ||
| 1006 | exception{ | ||
| 1007 | "*" => | ||
| 1008 | error("malformed header " + s); | ||
| 1009 | return nil; | ||
| 1010 | } | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | Mesg.mkmail(b : ref Box, hdr : string) | ||
| 1014 | { | ||
| 1015 | r : ref Mesg; | ||
| 1016 | |||
| 1017 | r = newmesg(); | ||
| 1018 | r.hdr = hdr + "\n"; | ||
| 1019 | r.lline1 = len r.hdr; | ||
| 1020 | r.text = nil; | ||
| 1021 | r.box = b; | ||
| 1022 | r.open(); | ||
| 1023 | r.w.wdormant(); | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | replyaddr(r : string) : string | ||
| 1027 | { | ||
| 1028 | p, q, rr : int; | ||
| 1029 | |||
| 1030 | rr = 0; | ||
| 1031 | while(r[rr]==' ' || r[rr]=='\t') | ||
| 1032 | rr++; | ||
| 1033 | r = r[rr:]; | ||
| 1034 | p = strchr(r, '<'); | ||
| 1035 | if(p >= 0){ | ||
| 1036 | q = strchr(r[p+1:], '>'); | ||
| 1037 | if(q < 0) | ||
| 1038 | r = r[p+1:]; | ||
| 1039 | else | ||
| 1040 | r = r[p+1:p+q] + "\n"; | ||
| 1041 | return r; | ||
| 1042 | } | ||
| 1043 | p = strchr(r, '('); | ||
| 1044 | if(p >= 0){ | ||
| 1045 | q = strchr(r[p:], ')'); | ||
| 1046 | if(q < 0) | ||
| 1047 | r = r[0:p]; | ||
| 1048 | else | ||
| 1049 | r = r[0:p] + r[p+q+1:]; | ||
| 1050 | } | ||
| 1051 | return r; | ||
664 more lines aren’t shown here.
This diff is large: its 1685 lines aren’t shown here.
This diff is large: its 1721 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 381 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 611 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 281 lines aren’t shown here.
This diff is large: its 137 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 1351 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 677 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 354 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 1351 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 332 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 1190 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 867 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 744 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 1051 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 768 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 188 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 175 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 1405 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 575 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 559 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 1088 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 1678 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 414 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 302 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 758 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 211 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 190 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 173 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 193 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 267 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 417 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 260 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 138 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 230 lines aren’t shown here.
This diff is large: its 305 lines aren’t shown here.
This diff is large: its 190 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 181 lines aren’t shown here.
This diff is large: its 230 lines aren’t shown here.
This diff is large: its 227 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 2865 lines aren’t shown here.
This diff is large: its 479 lines aren’t shown here.
This diff is large: its 2172 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 2046 lines aren’t shown here.
This diff is large: its 371 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 596 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 274 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 315 lines aren’t shown here.
This diff is large: its 561 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 1041 lines aren’t shown here.
This diff is large: its 3608 lines aren’t shown here.
This diff is large: its 116 lines aren’t shown here.
This diff is large: its 3026 lines aren’t shown here.
This diff is large: its 4833 lines aren’t shown here.
This diff is large: its 236 lines aren’t shown here.
This diff is large: its 1341 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 512 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 621 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 226 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 622 lines aren’t shown here.
This diff is large: its 1505 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 454 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 858 lines aren’t shown here.
This diff is large: its 631 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 241 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 305 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 1067 lines aren’t shown here.
This diff is large: its 322 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 205 lines aren’t shown here.
This diff is large: its 432 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 238 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 807 lines aren’t shown here.
This diff is large: its 200 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 291 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 333 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 351 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 492 lines aren’t shown here.
This diff is large: its 223 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 860 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 213 lines aren’t shown here.
This diff is large: its 296 lines aren’t shown here.
This diff is large: its 2548 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 248 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 152 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 1925 lines aren’t shown here.
This diff is large: its 238 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 264 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 519 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 626 lines aren’t shown here.
This diff is large: its 149 lines aren’t shown here.
This diff is large: its 855 lines aren’t shown here.
This diff is large: its 251 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 756 lines aren’t shown here.
This diff is large: its 912 lines aren’t shown here.
This diff is large: its 3845 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 135 lines aren’t shown here.
This diff is large: its 353 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 733 lines aren’t shown here.
This diff is large: its 455 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 175 lines aren’t shown here.
This diff is large: its 925 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 504 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 509 lines aren’t shown here.
This diff is large: its 3432 lines aren’t shown here.
This diff is large: its 164 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 1589 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 613 lines aren’t shown here.
This diff is large: its 313 lines aren’t shown here.
This diff is large: its 205 lines aren’t shown here.
This diff is large: its 561 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 196 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 649 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 188 lines aren’t shown here.
This diff is large: its 187 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 224 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 394 lines aren’t shown here.
This diff is large: its 131 lines aren’t shown here.
This diff is large: its 145 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 260 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 234 lines aren’t shown here.
This diff is large: its 112 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 1956 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 75 lines aren’t shown here.
This diff is large: its 249 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 229 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 700 lines aren’t shown here.
This diff is large: its 289 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 580 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 268 lines aren’t shown here.
This diff is large: its 446 lines aren’t shown here.
This diff is large: its 358 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 501 lines aren’t shown here.
This diff is large: its 431 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 288 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 240 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 321 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 210 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 387 lines aren’t shown here.
This diff is large: its 149 lines aren’t shown here.
This diff is large: its 205 lines aren’t shown here.
This diff is large: its 685 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 306 lines aren’t shown here.
This diff is large: its 636 lines aren’t shown here.
This diff is large: its 662 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 470 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 323 lines aren’t shown here.
This diff is large: its 783 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 172 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 359 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 469 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 217 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 284 lines aren’t shown here.
This diff is large: its 374 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 626 lines aren’t shown here.
This diff is large: its 311 lines aren’t shown here.
This diff is large: its 513 lines aren’t shown here.
This diff is large: its 127 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 479 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.
This diff is large: its 147 lines aren’t shown here.
This diff is large: its 215 lines aren’t shown here.
This diff is large: its 385 lines aren’t shown here.
This diff is large: its 295 lines aren’t shown here.
This diff is large: its 604 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 241 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 264 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 264 lines aren’t shown here.
This diff is large: its 1403 lines aren’t shown here.
This diff is large: its 1178 lines aren’t shown here.
This diff is large: its 561 lines aren’t shown here.
This diff is large: its 356 lines aren’t shown here.
This diff is large: its 2346 lines aren’t shown here.
This diff is large: its 1012 lines aren’t shown here.
This diff is large: its 248 lines aren’t shown here.
This diff is large: its 1179 lines aren’t shown here.
This diff is large: its 3101 lines aren’t shown here.
This diff is large: its 528 lines aren’t shown here.
This diff is large: its 1975 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 1403 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 398 lines aren’t shown here.
This diff is large: its 576 lines aren’t shown here.
This diff is large: its 3224 lines aren’t shown here.
This diff is large: its 4235 lines aren’t shown here.
This diff is large: its 262 lines aren’t shown here.
This diff is large: its 779 lines aren’t shown here.
This diff is large: its 260 lines aren’t shown here.
This diff is large: its 385 lines aren’t shown here.
This diff is large: its 333 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 947 lines aren’t shown here.
This diff is large: its 1367 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 348 lines aren’t shown here.
This diff is large: its 229 lines aren’t shown here.
This diff is large: its 200 lines aren’t shown here.
This diff is large: its 402 lines aren’t shown here.
This diff is large: its 159 lines aren’t shown here.
This diff is large: its 2786 lines aren’t shown here.
This diff is large: its 224 lines aren’t shown here.
This diff is large: its 207 lines aren’t shown here.
This diff is large: its 548 lines aren’t shown here.
This diff is large: its 724 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 373 lines aren’t shown here.
This diff is large: its 270 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 663 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 314 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 266 lines aren’t shown here.
This diff is large: its 604 lines aren’t shown here.
This diff is large: its 544 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 538 lines aren’t shown here.
This diff is large: its 649 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 4191 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 230 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 347 lines aren’t shown here.
This diff is large: its 395 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 194 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 261 lines aren’t shown here.
This diff is large: its 184 lines aren’t shown here.
This diff is large: its 687 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 1872 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 136 lines aren’t shown here.
This diff is large: its 777 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 158 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 142 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 844 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 902 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 767 lines aren’t shown here.
This diff is large: its 244 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 184 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 813 lines aren’t shown here.
This diff is large: its 171 lines aren’t shown here.
This diff is large: its 1231 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 621 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 912 lines aren’t shown here.
This diff is large: its 253 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 245 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 282 lines aren’t shown here.
This diff is large: its 460 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 349 lines aren’t shown here.
This diff is large: its 436 lines aren’t shown here.
This diff is large: its 221 lines aren’t shown here.
This diff is large: its 272 lines aren’t shown here.
This diff is large: its 2877 lines aren’t shown here.
This diff is large: its 2629 lines aren’t shown here.
This diff is large: its 813 lines aren’t shown here.
This diff is large: its 213 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 439 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 503 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 547 lines aren’t shown here.
This diff is large: its 263 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 380 lines aren’t shown here.
This diff is large: its 439 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 205 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 470 lines aren’t shown here.
This diff is large: its 285 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 279 lines aren’t shown here.
This diff is large: its 320 lines aren’t shown here.
This diff is large: its 214 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 1062 lines aren’t shown here.
This diff is large: its 772 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 836 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 468 lines aren’t shown here.
This diff is large: its 206 lines aren’t shown here.
This diff is large: its 330 lines aren’t shown here.
This diff is large: its 172 lines aren’t shown here.
This diff is large: its 304 lines aren’t shown here.
This diff is large: its 572 lines aren’t shown here.
This diff is large: its 192 lines aren’t shown here.
This diff is large: its 557 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 317 lines aren’t shown here.
This diff is large: its 2810 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 225 lines aren’t shown here.
This diff is large: its 283 lines aren’t shown here.
This diff is large: its 331 lines aren’t shown here.
This diff is large: its 587 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 157 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 178 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 264 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 302 lines aren’t shown here.
This diff is large: its 227 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 2558 lines aren’t shown here.
Binary file not shown.
Binary file not shown.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 2509 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 269 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 368 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 295 lines aren’t shown here.
This diff is large: its 602 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 241 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 330 lines aren’t shown here.
This diff is large: its 264 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 429 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 269 lines aren’t shown here.
This diff is large: its 606 lines aren’t shown here.
This diff is large: its 133 lines aren’t shown here.
This diff is large: its 180 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 525 lines aren’t shown here.
This diff is large: its 281 lines aren’t shown here.
This diff is large: its 1894 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 277 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 1798 lines aren’t shown here.
This diff is large: its 121 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 157 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 380 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 147 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 3 lines aren’t shown here.
This diff is large: its 978 lines aren’t shown here.
This diff is large: its 918 lines aren’t shown here.
This diff is large: its 213 lines aren’t shown here.
This diff is large: its 655 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 263 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 1179 lines aren’t shown here.
This diff is large: its 98 lines aren’t shown here.
This diff is large: its 391 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 4 lines aren’t shown here.
This diff is large: its 720 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 400 lines aren’t shown here.
This diff is large: its 1147 lines aren’t shown here.
This diff is large: its 240 lines aren’t shown here.
This diff is large: its 306 lines aren’t shown here.
This diff is large: its 280 lines aren’t shown here.
This diff is large: its 428 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 1031 lines aren’t shown here.
This diff is large: its 487 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 327 lines aren’t shown here.
This diff is large: its 343 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 535 lines aren’t shown here.
This diff is large: its 235 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 166 lines aren’t shown here.
This diff is large: its 180 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 163 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 1791 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 7815 lines aren’t shown here.
This diff is large: its 1144 lines aren’t shown here.
This diff is large: its 118 lines aren’t shown here.
This diff is large: its 6959 lines aren’t shown here.
This diff is large: its 6147 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 573 lines aren’t shown here.
This diff is large: its 5558 lines aren’t shown here.
This diff is large: its 177 lines aren’t shown here.
This diff is large: its 4126 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 512 lines aren’t shown here.
This diff is large: its 254 lines aren’t shown here.
This diff is large: its 464 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 1497 lines aren’t shown here.
This diff is large: its 1454 lines aren’t shown here.
This diff is large: its 124 lines aren’t shown here.
This diff is large: its 1030 lines aren’t shown here.
This diff is large: its 385 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 610 lines aren’t shown here.
This diff is large: its 123 lines aren’t shown here.
This diff is large: its 364 lines aren’t shown here.
This diff is large: its 243 lines aren’t shown here.
This diff is large: its 1481 lines aren’t shown here.
This diff is large: its 496 lines aren’t shown here.
This diff is large: its 2627 lines aren’t shown here.
This diff is large: its 864 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 837 lines aren’t shown here.
This diff is large: its 379 lines aren’t shown here.
This diff is large: its 1287 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 522 lines aren’t shown here.
This diff is large: its 170 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 401 lines aren’t shown here.
This diff is large: its 386 lines aren’t shown here.
This diff is large: its 148 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 665 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 229 lines aren’t shown here.
This diff is large: its 65550 lines aren’t shown here.
Binary file not shown.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 739 lines aren’t shown here.
This diff is large: its 821 lines aren’t shown here.
This diff is large: its 657 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 119 lines aren’t shown here.
This diff is large: its 100 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 620 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 149 lines aren’t shown here.
This diff is large: its 250 lines aren’t shown here.
This diff is large: its 143 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 176 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 248 lines aren’t shown here.
This diff is large: its 149 lines aren’t shown here.
This diff is large: its 153 lines aren’t shown here.
This diff is large: its 155 lines aren’t shown here.
This diff is large: its 278 lines aren’t shown here.
This diff is large: its 466 lines aren’t shown here.
This diff is large: its 915 lines aren’t shown here.
This diff is large: its 345 lines aren’t shown here.
This diff is large: its 505 lines aren’t shown here.
This diff is large: its 577 lines aren’t shown here.
This diff is large: its 704 lines aren’t shown here.
This diff is large: its 807 lines aren’t shown here.
This diff is large: its 255 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 191 lines aren’t shown here.
This diff is large: its 291 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is larger than a page shows: the files after these aren’t listed. Clone the repository to see all of it.