picolisp

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/picolisp.git/
Log | Files | Refs | README | LICENSE

commit 5abc0b66057a361eb68c241cfcba5aa6b63d73c3
parent 16308d53306b0dbb774d9443d72663f167766b74
Author: Alexander Burger <abu@software-lab.de>
Date:   Wed,  9 Mar 2011 18:09:14 +0100

Added 'err' (stderr redirection) function
Diffstat:
MCHANGES | 1+
MReleaseNotes | 5++++-
Mdoc/ref.html | 5+++--
Mdoc/refC.html | 5+++--
Mdoc/refE.html | 16++++++++++++++++
Mdoc/refI.html | 1+
Mdoc/refO.html | 5+++--
Mdoc64/structures | 4++--
Mersatz/picolisp.jar | 0
Mlib/tags | 79++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/io.c | 81++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/main.c | 6+++++-
Msrc/pico.h | 12+++++++++++-
Msrc/tab.c | 1+
Msrc/vers.h | 2+-
Msrc64/err.l | 14++++++++++++--
Msrc64/glob.l | 6++++--
Msrc64/io.l | 116++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------
Msrc64/version.l | 4++--
Mtest/src/io.l | 7++++++-
20 files changed, 277 insertions(+), 93 deletions(-)

diff --git a/CHANGES b/CHANGES @@ -1,4 +1,5 @@ * XXmar11 picoLisp-3.0.6 + 'err' function Removed 'rpc' function man pages for 'picolisp' and 'pil' 'version' also for 32-bit diff --git a/ReleaseNotes b/ReleaseNotes @@ -39,7 +39,7 @@ 5. The name of the GUI function 'err' in "lib/form.l" was changed to 'error' (and also that of the corresponding default CSS type in "lib.css"). This was - done to reserve the name "err" for future standard error redirection. + done to reserve the name "err" for standard error redirection (point 8). 6. The "opt/" directory (until now containing only a single "pilog.l" file) was removed from the base distribution. It is now tracked separately. To install @@ -51,3 +51,6 @@ 7. The 'rpc' function was removed from the release. It is seldom used, and also redundant: (rpc 'foo ''arg) is equivalent to (pr '(foo 'arg)) + +8. A new function 'err' for standard error redirection is now available. It is + analog to 'out', but accepts only a symbolic argument (like 'ctl'). diff --git a/doc/ref.html b/doc/ref.html @@ -2164,11 +2164,12 @@ abbreviations: <dd><code> <a href="refP.html#path">path</a> <a href="refI.html#in">in</a> - <a href="refI.html#ipid">ipid</a> <a href="refO.html#out">out</a> + <a href="refE.html#err">err</a> + <a href="refC.html#ctl">ctl</a> + <a href="refI.html#ipid">ipid</a> <a href="refO.html#opid">opid</a> <a href="refP.html#pipe">pipe</a> - <a href="refC.html#ctl">ctl</a> <a href="refA.html#any">any</a> <a href="refS.html#sym">sym</a> <a href="refS.html#str">str</a> diff --git a/doc/refC.html b/doc/refC.html @@ -619,8 +619,9 @@ files does not exist, it will be created. When <code>sym</code> is <code>NIL</code>, a shared lock is tried on the current innermost I/O channel, and when it is <code>T</code>, an exclusive lock is tried instead. See also <code><a href="refI.html#in">in</a></code>, <code><a -href="refP.html#pipe">pipe</a></code> and <code><a -href="refO.html#out">out</a></code>. +href="refO.html#out">out</a></code>, <code><a +href="refE.html#err">err</a></code> and <code><a +href="refP.html#pipe">pipe</a></code>. <pre><code> $ echo 9 >count # Write '9' to file "count" diff --git a/doc/refE.html b/doc/refE.html @@ -267,6 +267,22 @@ href="refM.html#member/2">member/2</a></code>. -> NIL </code></pre> +<dt><a name="err"><code>(err 'sym . prg) -> any</code></a> +<dd>Redirects the standard error stream to <code>sym</code> during the execution +of <code>prg</code>. The current standard error stream will be saved and +restored appropriately. If the argument is <code>NIL</code>, the current output +stream will be used. Otherwise, <code>sym</code> is taken as a file name (opened +in "append" mode if the first character is "+"), where standard error is to be +written to. See also <code><a href="refI.html#in">in</a></code>, <code><a +href="refO.html#out">out</a></code> and <code><a +href="refC.html#ctl">ctl</a></code>. + +<pre><code> +: (err "/dev/null" # Suppress error messages + (call 'ls 'noSuchFile) ) +-> NIL +</code></pre> + <dt><a name="errno"><code>(errno) -> cnt</code></a> <dd>(64-bit version only) Returns the value of the standard I/O 'errno' variable. diff --git a/doc/refI.html b/doc/refI.html @@ -168,6 +168,7 @@ href="refC.html#call">call</a></code>, <code><a href="refL.html#load">load</a></code>, <code><a href="refF.html#file">file</a></code>, <code><a href="refO.html#out">out</a></code>, <code><a +href="refE.html#err">err</a></code>, <code><a href="refP.html#poll">poll</a></code>, <code><a href="refP.html#pipe">pipe</a></code> and <code><a href="refC.html#ctl">ctl</a></code>. diff --git a/doc/refO.html b/doc/refO.html @@ -254,9 +254,10 @@ list), it is taken as a command with arguments, and a pipe is opened for output. See also <code><a href="refO.html#opid">opid</a></code>, <code> <a href="refC.html#call">call</a></code>, <code><a href="refI.html#in">in</a></code>, <code> <a -href="refP.html#poll">poll</a></code>, <code> <a -href="refP.html#pipe">pipe</a></code>, <code> <a +href="refE.html#err">err</a></code>, <code> <a href="refC.html#ctl">ctl</a></code>, <code><a +href="refP.html#pipe">pipe</a></code>, <code> <a +href="refP.html#poll">poll</a></code>, <code> <a href="refC.html#close">close</a></code> and <code><a href="refL.html#load">load</a></code>. diff --git a/doc64/structures b/doc64/structures @@ -1,4 +1,4 @@ -# 03feb11abu +# 09mar11abu # (c) Software Lab. Alexander Burger @@ -208,7 +208,7 @@ <III> put/get | <II> pid | <I> fd | - LINK ----+ <-- inFrames, outFrames, ctlFrames + LINK ----+ <-- inFrames, outFrames, errFrames, ctlFrames Coroutine frame: diff --git a/ersatz/picolisp.jar b/ersatz/picolisp.jar Binary files differ. diff --git a/lib/tags b/lib/tags @@ -29,7 +29,7 @@ adr (603 . "@src64/main.l") alarm (480 . "@src64/main.l") all (772 . "@src64/sym.l") and (1621 . "@src64/flow.l") -any (3879 . "@src64/io.l") +any (3933 . "@src64/io.l") append (1338 . "@src64/subr.l") apply (713 . "@src64/apply.l") arg (2270 . "@src64/main.l") @@ -82,12 +82,12 @@ cdddr (245 . "@src64/subr.l") cddr (79 . "@src64/subr.l") cdr (17 . "@src64/subr.l") chain (1141 . "@src64/subr.l") -char (3361 . "@src64/io.l") +char (3415 . "@src64/io.l") chop (1093 . "@src64/sym.l") circ (816 . "@src64/subr.l") circ? (2398 . "@src64/subr.l") clip (1795 . "@src64/subr.l") -close (4267 . "@src64/io.l") +close (4339 . "@src64/io.l") cmd (2873 . "@src64/main.l") cnt (1413 . "@src64/apply.l") co (2546 . "@src64/flow.l") @@ -98,7 +98,7 @@ cond (1916 . "@src64/flow.l") connect (201 . "@src64/net.l") cons (747 . "@src64/subr.l") copy (1225 . "@src64/subr.l") -ctl (4207 . "@src64/io.l") +ctl (4217 . "@src64/io.l") ctty (2671 . "@src64/main.l") cut (1797 . "@src64/sym.l") date (2385 . "@src64/main.l") @@ -115,13 +115,14 @@ dir (2804 . "@src64/main.l") dm (543 . "@src64/flow.l") do (2138 . "@src64/flow.l") e (2920 . "@src64/flow.l") -echo (4298 . "@src64/io.l") +echo (4370 . "@src64/io.l") env (615 . "@src64/main.l") -eof (3438 . "@src64/io.l") -eol (3429 . "@src64/io.l") +eof (3492 . "@src64/io.l") +eol (3483 . "@src64/io.l") +err (4197 . "@src64/io.l") errno (1381 . "@src64/main.l") eval (182 . "@src64/flow.l") -ext (5028 . "@src64/io.l") +ext (5100 . "@src64/io.l") ext? (1034 . "@src64/sym.l") extern (900 . "@src64/sym.l") extra (1263 . "@src64/flow.l") @@ -136,13 +137,13 @@ find (1322 . "@src64/apply.l") fish (1613 . "@src64/apply.l") flg? (2441 . "@src64/subr.l") flip (1695 . "@src64/subr.l") -flush (5003 . "@src64/io.l") +flush (5075 . "@src64/io.l") fold (3343 . "@src64/sym.l") for (2227 . "@src64/flow.l") fork (3264 . "@src64/flow.l") format (2089 . "@src64/big.l") free (2047 . "@src64/db.l") -from (3457 . "@src64/io.l") +from (3511 . "@src64/io.l") full (1075 . "@src64/subr.l") fun? (734 . "@src64/sym.l") gc (432 . "@src64/gc.l") @@ -154,14 +155,14 @@ glue (1234 . "@src64/sym.l") gt0 (2716 . "@src64/big.l") head (1816 . "@src64/subr.l") heap (535 . "@src64/main.l") -hear (3142 . "@src64/io.l") +hear (3196 . "@src64/io.l") host (184 . "@src64/net.l") id (1027 . "@src64/db.l") idx (2037 . "@src64/sym.l") if (1802 . "@src64/flow.l") if2 (1821 . "@src64/flow.l") ifn (1862 . "@src64/flow.l") -in (4103 . "@src64/io.l") +in (4157 . "@src64/io.l") inc (2256 . "@src64/big.l") index (2633 . "@src64/subr.l") info (2708 . "@src64/main.l") @@ -170,7 +171,7 @@ ipid (3209 . "@src64/flow.l") isa (959 . "@src64/flow.l") job (1426 . "@src64/flow.l") journal (970 . "@src64/db.l") -key (3290 . "@src64/io.l") +key (3344 . "@src64/io.l") kill (3241 . "@src64/flow.l") last (2040 . "@src64/subr.l") le0 (2691 . "@src64/big.l") @@ -178,14 +179,14 @@ length (2737 . "@src64/subr.l") let (1476 . "@src64/flow.l") let? (1537 . "@src64/flow.l") lieu (1156 . "@src64/db.l") -line (3613 . "@src64/io.l") -lines (3766 . "@src64/io.l") +line (3667 . "@src64/io.l") +lines (3820 . "@src64/io.l") link (1172 . "@src64/subr.l") lisp (1948 . "@src64/main.l") list (887 . "@src64/subr.l") listen (151 . "@src64/net.l") lit (157 . "@src64/flow.l") -load (4080 . "@src64/io.l") +load (4134 . "@src64/io.l") lock (1184 . "@src64/db.l") loop (2170 . "@src64/flow.l") low? (3215 . "@src64/sym.l") @@ -235,30 +236,30 @@ offset (2673 . "@src64/subr.l") on (1583 . "@src64/sym.l") onOff (1613 . "@src64/sym.l") one (1646 . "@src64/sym.l") -open (4229 . "@src64/io.l") +open (4301 . "@src64/io.l") opid (3225 . "@src64/flow.l") opt (2994 . "@src64/main.l") or (1637 . "@src64/flow.l") -out (4123 . "@src64/io.l") +out (4177 . "@src64/io.l") pack (1144 . "@src64/sym.l") pair (2390 . "@src64/subr.l") pass (754 . "@src64/apply.l") pat? (720 . "@src64/sym.l") path (1238 . "@src64/io.l") -peek (3345 . "@src64/io.l") +peek (3399 . "@src64/io.l") pick (1369 . "@src64/apply.l") -pipe (4144 . "@src64/io.l") -poll (3234 . "@src64/io.l") +pipe (4238 . "@src64/io.l") +poll (3288 . "@src64/io.l") pool (648 . "@src64/db.l") pop (1773 . "@src64/sym.l") port (5 . "@src64/net.l") -pr (5111 . "@src64/io.l") +pr (5183 . "@src64/io.l") pre? (1411 . "@src64/sym.l") -prin (4927 . "@src64/io.l") -prinl (4941 . "@src64/io.l") -print (4967 . "@src64/io.l") -println (4998 . "@src64/io.l") -printsp (4983 . "@src64/io.l") +prin (4999 . "@src64/io.l") +prinl (5013 . "@src64/io.l") +print (5039 . "@src64/io.l") +println (5070 . "@src64/io.l") +printsp (5055 . "@src64/io.l") prior (2709 . "@src64/subr.l") prog (1757 . "@src64/flow.l") prog1 (1765 . "@src64/flow.l") @@ -278,12 +279,12 @@ rand (2973 . "@src64/big.l") range (997 . "@src64/subr.l") rank (3029 . "@src64/subr.l") raw (458 . "@src64/main.l") -rd (5045 . "@src64/io.l") -read (2573 . "@src64/io.l") +rd (5117 . "@src64/io.l") +read (2627 . "@src64/io.l") replace (1499 . "@src64/subr.l") rest (2299 . "@src64/main.l") reverse (1674 . "@src64/subr.l") -rewind (5011 . "@src64/io.l") +rewind (5083 . "@src64/io.l") rollback (1890 . "@src64/db.l") rot (848 . "@src64/subr.l") run (313 . "@src64/flow.l") @@ -296,31 +297,31 @@ set (1482 . "@src64/sym.l") setq (1515 . "@src64/sym.l") sigio (496 . "@src64/main.l") size (2802 . "@src64/subr.l") -skip (3415 . "@src64/io.l") +skip (3469 . "@src64/io.l") sort (3958 . "@src64/subr.l") sp? (711 . "@src64/sym.l") -space (4945 . "@src64/io.l") +space (5017 . "@src64/io.l") split (1588 . "@src64/subr.l") stack (564 . "@src64/main.l") state (2006 . "@src64/flow.l") stem (1985 . "@src64/subr.l") -str (3933 . "@src64/io.l") +str (3987 . "@src64/io.l") str? (1013 . "@src64/sym.l") strip (1572 . "@src64/subr.l") sub? (1444 . "@src64/sym.l") sum (1460 . "@src64/apply.l") super (1218 . "@src64/flow.l") -sym (3919 . "@src64/io.l") +sym (3973 . "@src64/io.l") sym? (2430 . "@src64/subr.l") -sync (3102 . "@src64/io.l") +sync (3156 . "@src64/io.l") sys (3061 . "@src64/flow.l") t (1748 . "@src64/flow.l") tail (1907 . "@src64/subr.l") -tell (3174 . "@src64/io.l") +tell (3228 . "@src64/io.l") text (1272 . "@src64/sym.l") throw (2490 . "@src64/flow.l") tick (3177 . "@src64/flow.l") -till (3524 . "@src64/io.l") +till (3578 . "@src64/io.l") time (2518 . "@src64/main.l") touch (1049 . "@src64/sym.l") trim (1755 . "@src64/subr.l") @@ -337,12 +338,12 @@ use (1570 . "@src64/flow.l") usec (2623 . "@src64/main.l") val (1463 . "@src64/sym.l") version (3008 . "@src64/main.l") -wait (3064 . "@src64/io.l") +wait (3118 . "@src64/io.l") when (1881 . "@src64/flow.l") while (2058 . "@src64/flow.l") wipe (3090 . "@src64/sym.l") with (1327 . "@src64/flow.l") -wr (5128 . "@src64/io.l") +wr (5200 . "@src64/io.l") xchg (1538 . "@src64/sym.l") xor (1698 . "@src64/flow.l") x| (2885 . "@src64/big.l") diff --git a/src/io.c b/src/io.c @@ -795,6 +795,38 @@ void wrOpen(any ex, any x, outFrame *f) { } } +void erOpen(any ex, any x, errFrame *f) { + int fd; + + NeedSym(ex,x); + f->fd = dup(STDERR_FILENO); + if (isNil(x)) + fd = dup(OutFile->fd); + else { + char nm[pathSize(x)]; + + pathString(x,nm); + if (nm[0] == '+') { + while ((fd = open(nm+1, O_APPEND|O_CREAT|O_WRONLY, 0666)) < 0) { + if (errno != EINTR) + openErr(ex, nm); + if (*Signal) + sighandler(ex); + } + } + else { + while ((fd = open(nm, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0) { + if (errno != EINTR) + openErr(ex, nm); + if (*Signal) + sighandler(ex); + } + } + closeOnExec(ex, fd); + } + dup2(fd, STDERR_FILENO), close(fd); +} + void ctOpen(any ex, any x, ctlFrame *f) { NeedSym(ex,x); if (isNil(x)) { @@ -882,6 +914,10 @@ void pushOutFiles(outFrame *f) { f->link = Env.outFrames, Env.outFrames = f; } +void pushErrFiles(errFrame *f) { + f->link = Env.errFrames, Env.errFrames = f; +} + void pushCtlFiles(ctlFrame *f) { f->link = Env.ctlFrames, Env.ctlFrames = f; } @@ -921,6 +957,12 @@ void popOutFiles(void) { OutFile = OutFiles[(Env.outFrames = Env.outFrames->link)? Env.outFrames->fd : STDOUT_FILENO]; } +void popErrFiles(void) { + dup2(Env.errFrames->fd, STDERR_FILENO); + close(Env.errFrames->fd); + Env.errFrames = Env.errFrames->link; +} + void popCtlFiles(void) { if (Env.ctlFrames->fd >= 0) close(Env.ctlFrames->fd); @@ -2064,6 +2106,32 @@ any doOut(any ex) { return x; } +// (err 'sym . prg) -> any +any doErr(any ex) { + any x; + errFrame f; + + x = cdr(ex), x = EVAL(car(x)); + erOpen(ex,x,&f); + pushErrFiles(&f); + x = prog(cddr(ex)); + popErrFiles(); + return x; +} + +// (ctl 'sym . prg) -> any +any doCtl(any ex) { + any x; + ctlFrame f; + + x = cdr(ex), x = EVAL(car(x)); + ctOpen(ex,x,&f); + pushCtlFiles(&f); + x = prog(cddr(ex)); + popCtlFiles(); + return x; +} + // (pipe exe) -> cnt // (pipe exe . prg) -> any any doPipe(any ex) { @@ -2101,19 +2169,6 @@ any doPipe(any ex) { return x; } -// (ctl 'sym . prg) -> any -any doCtl(any ex) { - any x; - ctlFrame f; - - x = cdr(ex), x = EVAL(car(x)); - ctOpen(ex,x,&f); - pushCtlFiles(&f); - x = prog(cddr(ex)); - popCtlFiles(); - return x; -} - // (open 'any) -> cnt | NIL any doOpen(any ex) { any x = evSym(cdr(ex)); diff --git a/src/main.c b/src/main.c @@ -1,4 +1,4 @@ -/* 07mar11abu +/* 09mar11abu * (c) Software Lab. Alexander Burger */ @@ -616,6 +616,8 @@ void unwind(catchFrame *catch) { popInFiles(); while (Env.outFrames != q->env.outFrames) popOutFiles(); + while (Env.errFrames != q->env.errFrames) + popErrFiles(); while (Env.ctlFrames != q->env.ctlFrames) popCtlFiles(); Env = q->env; @@ -634,6 +636,8 @@ void unwind(catchFrame *catch) { popInFiles(); while (Env.outFrames) popOutFiles(); + while (Env.errFrames) + popErrFiles(); while (Env.ctlFrames) popCtlFiles(); } diff --git a/src/pico.h b/src/pico.h @@ -102,6 +102,11 @@ typedef struct outFrame { int fd; } outFrame; +typedef struct errFrame { + struct errFrame *link; + int fd; +} errFrame; + typedef struct ctlFrame { struct ctlFrame *link; int fd; @@ -119,6 +124,7 @@ typedef struct stkEnv { any cls, key, task, *make, *yoke; inFrame *inFrames; outFrame *outFrames; + errFrame *errFrames; ctlFrame *ctlFrames; parseFrame *parser; void (*get)(void); @@ -298,6 +304,7 @@ unsigned long ehash(any); any endString(void); bool eol(void); bool equal(any,any); +void erOpen(any,any,errFrame*); void err(any,any,char*,...) __attribute__ ((noreturn)); any evExpr(any,any); long evCnt(any,any); @@ -354,6 +361,7 @@ void pathString(any,char*); void pipeError(any,char*); void popCtlFiles(void); void popInFiles(void); +void popErrFiles(void); void popOutFiles(void); void pr(int,any); void prin(any); @@ -362,9 +370,10 @@ void print(any); void print1(any); void prn(long); void protError(any,any) __attribute__ ((noreturn)); +void pushCtlFiles(ctlFrame*); void pushInFiles(inFrame*); +void pushErrFiles(errFrame*); void pushOutFiles(outFrame*); -void pushCtlFiles(ctlFrame*); void put(any,any,any); void putStdout(int); void rdOpen(any,any,inFrame*); @@ -500,6 +509,7 @@ any doEq(any); any doEq0(any); any doEqT(any); any doEqual(any); +any doErr(any); any doEval(any); any doExt(any); any doExtern(any); diff --git a/src/tab.c b/src/tab.c @@ -114,6 +114,7 @@ static symInit Symbols[] = { {doEq0, "=0"}, {doEqT, "=T"}, {doEqual, "="}, + {doErr, "err"}, {doEval, "eval"}, {doExt, "ext"}, {doExtern, "extern"}, diff --git a/src/vers.h b/src/vers.h @@ -1 +1 @@ -static byte Version[4] = {3,0,5,21}; +static byte Version[4] = {3,0,5,22}; diff --git a/src64/err.l b/src64/err.l @@ -1,4 +1,4 @@ -# 01mar11abu +# 09mar11abu # (c) Software Lab. Alexander Burger # Debug print routine @@ -241,7 +241,12 @@ call popOutFiles # Clean up loop do - cmp (EnvCtlFrames) (X VI) # Open control frames? + cmp (EnvErrFrames) (X VI) # Open error frames? + while ne # Yes + call popErrFiles # Clean up + loop + do + cmp (EnvCtlFrames) (X VII) # Open control frames? while ne # Yes call popCtlFiles # Clean up loop @@ -304,6 +309,11 @@ call popOutFiles # Clean up loop do + null (EnvErrFrames) # Open error frames? + while nz # Yes + call popErrFiles # Clean up + loop + do null (EnvCtlFrames) # Open control frames? while nz # Yes call popCtlFiles # Clean up diff --git a/src64/glob.l b/src64/glob.l @@ -505,8 +505,9 @@ initFun NIL "load" doLoad initFun NIL "in" doIn initFun NIL "out" doOut - initFun NIL "pipe" doPipe + initFun NIL "err" doErr initFun NIL "ctl" doCtl + initFun NIL "pipe" doPipe initFun NIL "open" doOpen initFun NIL "close" doClose initFun NIL "echo" doEcho @@ -581,7 +582,8 @@ : EnvBind word 0 # <III> Bind frames (first item in Env) : EnvInFrames word 0 # <IV> Input frames : EnvOutFrames word 0 # <V> Output frames -: EnvCtlFrames word 0 # <VI> Control frames +: EnvErrFrames word 0 # <VI> Error frames +: EnvCtlFrames word 0 # <VII> Control frames : EnvArgs word 0 # Varargs frame : EnvNext word 0 # Next vararg : EnvCls word 0 # Method class diff --git a/src64/io.l b/src64/io.l @@ -1617,6 +1617,48 @@ end ret +(code 'erOpenEXY) + num E # Need symbol + jnz symErrEX + sym E + jz symErrEX + cc dup(2) # Duplicate current stderr + ld (Y I) A # Save it + cmp E Nil # Use current output channel? + if eq # Yes + cc dup(((OutFile))) # Duplicate 'fd' + ld C A # Keep in C + else + push Z + call pathStringE_SZ # File name + do + ld B (S) # First char + cmp B (char "+") # Plus? + if eq # Yes + cc open(&(S 1) (| O_APPEND O_CREAT O_WRONLY) (oct "0666")) + else + cc open(S (| O_CREAT O_TRUNC O_WRONLY) (oct "0666")) + end + nul4 # OK? + while s # No + call errno_A + cmp A EINTR # Interrupted? + jne openErrEX # No + null (Signal) # Signal? + if nz # Yes + call sighandlerX + end + loop + ld S Z # Drop buffer + pop Z + ld C A # Keep 'fd' in C + call closeOnExecAX + end + cc dup2(C 2) # Dup 'fd' to STDERR_FILENO + ld A C + call closeAX + ret + (code 'ctOpenEXY) num E # Need symbol jnz symErrEX @@ -1800,6 +1842,11 @@ ld (EnvOutFrames) Y # Link frame ret +(code 'pushErrFilesY) + ld (Y) (EnvErrFrames) # Set link + ld (EnvErrFrames) Y # Link frame + ret + (code 'pushCtlFilesY) ld (Y) (EnvCtlFrames) # Set link ld (EnvCtlFrames) Y # Link frame @@ -1896,6 +1943,13 @@ ld (OutFile) A # Set OutFile ret +(code 'popErrFiles) # C + ld C (EnvErrFrames) # Get ErrFrames + cc dup2((C I) 2) # Restore stderr + cc close((C I)) # Close 'fd' + ld (EnvErrFrames) ((EnvErrFrames)) # Restore ErrFrames + ret + (code 'popCtlFiles) # C ld C (EnvCtlFrames) # Get CtlFrames null (C I) # 'fd' >= 0? @@ -4139,6 +4193,46 @@ pop X ret +# (err 'sym . prg) -> any +(code 'doErr 2) + push X + push Y + ld X E # Expression in X + ld E (E CDR) + ld E (E) # Eval 'any' + eval + sub S II # ErrFrame + ld Y S + call erOpenEXY + call pushErrFilesY + ld X ((X CDR) CDR) # Get 'prg' + prog X + call popErrFiles + add S II # Drop ErrFrame + pop Y + pop X + ret + +# (ctl 'sym . prg) -> any +(code 'doCtl 2) + push X + push Y + ld X E # Expression in X + ld E (E CDR) + ld E (E) # Eval 'any' + eval + sub S II # CtlFrame + ld Y S + call ctOpenEXY + call pushCtlFilesY + ld X ((X CDR) CDR) # Get 'prg' + prog X + call popCtlFiles + add S II # Drop CtlFrame + pop Y + pop X + ret + # (pipe exe) -> cnt # (pipe exe . prg) -> any (code 'doPipe 2) @@ -4203,28 +4297,6 @@ pop X ret -# (ctl 'sym . prg) -> any -(code 'doCtl 2) - push X - push Y - ld X E # Expression in X - ld E (E CDR) - ld E (E) # Eval 'any' - eval - push A # CtlFrame - push A - ld Y S - call ctOpenEXY - call pushCtlFilesY - ld X ((X CDR) CDR) # Get 'prg' - prog X - call popCtlFiles - pop A # Drop CtlFrame - pop A - pop Y - pop X - ret - # (open 'sym) -> cnt | NIL (code 'doOpen 2) push X diff --git a/src64/version.l b/src64/version.l @@ -1,6 +1,6 @@ -# 07mar11abu +# 09mar11abu # (c) Software Lab. Alexander Burger -(de *Version 3 0 5 21) +(de *Version 3 0 5 22) # vi:et:ts=3:sw=3 diff --git a/test/src/io.l b/test/src/io.l @@ -112,7 +112,7 @@ (test 6 (load "-* 1 2 3")) -### in out ### +### in out err ### (out (tmp "file") (println 123) (println 'abc) @@ -124,6 +124,11 @@ (test 'abc (in -1 (read))) ) (test '(d e f) (read)) ) +(let Err (tmp "err") + (test 1 (err Err (msg 1))) + (test 2 (err (pack "+" Err) (msg 2))) + (test "1^J2^J" (in Err (till NIL T))) ) + ### pipe ### (test 123 (pipe (println 123) (read)))