rc-list - mailing list for the rc(1) shell
 help / color / mirror / Atom feed
* Re: A lighter read function
@ 1991-12-11  4:32 DaviD W. Sanderson
  1991-12-11 12:28 ` David J. Fiander
  0 siblings, 1 reply; 9+ messages in thread
From: DaviD W. Sanderson @ 1991-12-11  4:32 UTC (permalink / raw)
  To: rc

[Apologies to the list; I am unable to reply to "golem!david"]

> exactly the same functionality as the example source, except it
> uses line(1) and doesn't do the assignment if the read fails.

line(1) is not available everywhere.  At least not on the 4.3BSD-utah
systems I use.  Perhaps rephrasing in terms of `sed 1q' would be better.

DaviD W. Sanderson (dws@cs.wisc.edu)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: A lighter read function
  1991-12-11  4:32 A lighter read function DaviD W. Sanderson
@ 1991-12-11 12:28 ` David J. Fiander
  1991-12-11 19:28   ` Chris Siebenmann
  1991-12-11 21:48   ` Ronald S H Khoo
  0 siblings, 2 replies; 9+ messages in thread
From: David J. Fiander @ 1991-12-11 12:28 UTC (permalink / raw)
  To: DaviD W. Sanderson; +Cc: The rc user community

>> exactly the same functionality as the example source, except it
>> uses line(1) and doesn't do the assignment if the read fails.
>
>line(1) is not available everywhere.  At least not on the 4.3BSD-utah
>systems I use.  Perhaps rephrasing in terms of `sed 1q' would be better.

Try 'david%golem@lsuc.on.ca'.  True, but the problem with sed
is that it doesn't fail on EOF, which is true of line.

line is available on all SCO UNIX systems, and I first saw it
on a BSD 4.2 system (I think).  Besides it is easily written:

#include <stdio.h>

main(argc, argv)
int argc;
char **argv;
{
	char	buf[256];
	int	len;

	if (fgets(buf, sizeof(buf), stdin) == (char *)NULL) {
		fputs(buf, stdout);
		exit(0);
	} else
		exit(1);
}


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: A lighter read function
  1991-12-11 12:28 ` David J. Fiander
@ 1991-12-11 19:28   ` Chris Siebenmann
  1991-12-13  0:58     ` David J. Fiander
  1991-12-11 21:48   ` Ronald S H Khoo
  1 sibling, 1 reply; 9+ messages in thread
From: Chris Siebenmann @ 1991-12-11 19:28 UTC (permalink / raw)
  To: The rc user community

 This has come up before on the mailing list. One cannot use sed, awk,
or handgrown alternatives that use stdio when you are not reading from
a terminal, because their buffering will eat too much of the input
stream and then silently discard it when they exit. You can convince
yourself by defining read in terms of one of them and then doing:
	{echo A; echo B} | {read a; echo a $a; read b; echo b $b}
and noticing what comes out.

 line is safe, and trivial to write; I will happily mail my version
to anyone who wants it. It even comes with a manual page.

 Here is my current version of read along with a couple of functions
that it relies on:

# A real read function, as in 'read var var var'. Returns failure
# on EOF.  relies on the 'line' program.
nl='
'
fn read { _v=() _i=() {
	_v=`` $nl {line; echo $status}
	if (! ~ $_v(2) 0) return $_v(2);
	_v=`{echo $_v(1)}
	for (_i in $*) {
		$_i=$_v(1); sshift _v 1
	}
	$_i=($$_i $_v)
}; return 0; }

# 'supershift' function for rc.
# usage:
#	sshift varname
#	sshift varname number
# shifts the list varname by number (default 1) positions.
fn sshift { if (~ $#* 1 ) { _sshift $1 1 $$1 } else { _sshift $1 $2 $$1 } }

# this function does most of the work.
# _sshift NAME COUNT LISTELEMS
# shift LISTELEMS COUNT items left, and assign the result to NAME.
fn _sshift { _vn=() { _vn=$1; shift; shift $1; shift; $_vn=$* } }

	- cks


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: A lighter read function
  1991-12-11 12:28 ` David J. Fiander
  1991-12-11 19:28   ` Chris Siebenmann
@ 1991-12-11 21:48   ` Ronald S H Khoo
  1991-12-12 12:16     ` David J. Fiander
  1 sibling, 1 reply; 9+ messages in thread
From: Ronald S H Khoo @ 1991-12-11 21:48 UTC (permalink / raw)
  To: david; +Cc: rc


In article <22832.692454506@golem.UUCP> David J Fiander wrote:

> line is available on all SCO UNIX systems, and I first saw it
> on a BSD 4.2 system (I think).  Besides it is easily written:

> #include <stdio.h>

This looks wrong to me.  line(1) does not use stdio.  Where available,
line(1) should preserve the seek position of the stream so that anyone
who comes afterwards can read the rest.  Trying to fseek back there
ain't much good either, since input might come from a non-seekable
device or pipe.  Hence, line(1) must use single character reads, just
like sh(1) does (what does rc(1L) do ?).

Here is a demonstration of line(1)'s behaviour on a SCO UNIX machine:
script 'typescript' started on Wed Dec 11 21:31:34 1991
$ grep LSEEK /usr/include/sys.s
#define	LSEEK	19
$ (line > /dev/null
>  perl -e 'print syscall(19,0,0,1)."\n"'  # ie lseek(0, 0L, SEEK_CUR)
> ) < /etc/passwd
24
$ (sed 1q > /dev/null
>  perl -e 'print syscall(19,0,0,1)."\n"'
> ) < /etc/passwd
512
$ script 'typescript' ended on Wed Dec 11 21:33:10 1991

Please excuse the use of sh(1) -- I haven't had time to learn rc.
Please excuse the use of perl(1L) -- I couldn't think of another
way of executing lseek(2) from the command line ...

(BTW, David, in case anyone you know wants an "alternative" approach to
 script(1) on SCO, mine's 83 lines of perl :-)

-- 
Ronald Khoo <ronald@robobar.co.uk> +44 81 991 1142 (O) +44 71 229 7741 (H)


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: A lighter read function
  1991-12-11 21:48   ` Ronald S H Khoo
@ 1991-12-12 12:16     ` David J. Fiander
  0 siblings, 0 replies; 9+ messages in thread
From: David J. Fiander @ 1991-12-12 12:16 UTC (permalink / raw)
  To: Ronald S H Khoo; +Cc: rc


>From: 	ronald@robobar.co.uk (Ronald S H Khoo)
>
>This looks wrong to me.  line(1) does not use stdio.  Where available,
>line(1) should preserve the seek position of the stream so that anyone
>who comes afterwards can read the rest.  Trying to fseek back there

You're right.  I thought of this during the trip to work on the
subway.  But then, that will make the line binary even smaller.

- David


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: A lighter read function
  1991-12-11 19:28   ` Chris Siebenmann
@ 1991-12-13  0:58     ` David J. Fiander
  1991-12-13  1:37       ` Chris Siebenmann
  1991-12-13  1:47       ` David Hogan
  0 siblings, 2 replies; 9+ messages in thread
From: David J. Fiander @ 1991-12-13  0:58 UTC (permalink / raw)
  To: Chris Siebenmann; +Cc: The rc user community

>From: 	Chris Siebenmann <hawkwind.utcs.toronto.edu!cks@rutgers.uucp>
> Here is my current version of read along with a couple of functions
>that it relies on:

It looks pretty good.

>
># A real read function, as in 'read var var var'. Returns failure
># on EOF.  relies on the 'line' program.
>nl='
>'
>fn read { _v=() _i=() {
>	_v=`` $nl {line; echo $status}

This is why byron added the "``ifs{}" extension, but the Plan 9
way is probably

	ifs=$nl { _v=`{line; echo $status}}

which sets ifs for only the one command, but sets _v globally.

>	if (! ~ $_v(2) 0) return $_v(2);

There's a small problem with this.  If line sees an EOF, then
it will print a newline, and exit with status 1.  _v is thus
set to "1", since there is nothing before the first nl.  There
is no $_v(2), so the ~ fails, and read returns success.

I got around this by writing it as:

	x = `{line || echo 1^$nl^1; echo 0}

Then, if line fails, we get

	x = (1 1)

 otherwise we get

	x = ('the line' 0)

--
David J. Fiander   |email [Fr., = enamel] Used attrib. in `email ink', ink
<david@golem.uucp> |used on glass, porcelain, etc.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: A lighter read function
  1991-12-13  0:58     ` David J. Fiander
@ 1991-12-13  1:37       ` Chris Siebenmann
  1991-12-13  1:47       ` David Hogan
  1 sibling, 0 replies; 9+ messages in thread
From: Chris Siebenmann @ 1991-12-13  1:37 UTC (permalink / raw)
  To: The rc user community

 David's quite right; obviously I haven't tested my read function enough.
I'd make it
	_v=`` $nl {line; echo $status $nl $status}
since I don't want to count on line returning just 0 or 1 status.
And it should check $#_v too, just in case.

	- cks


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: A lighter read function
  1991-12-13  0:58     ` David J. Fiander
  1991-12-13  1:37       ` Chris Siebenmann
@ 1991-12-13  1:47       ` David Hogan
  1 sibling, 0 replies; 9+ messages in thread
From: David Hogan @ 1991-12-13  1:47 UTC (permalink / raw)
  To: rc whining list

"David J. Fiander"  writes:

> 	x = `{line || echo 1^$nl^1; echo 0}
>
> Then, if line fails, we get
>
> 	x = (1 1)
>
>  otherwise we get
>
> 	x = ('the line' 0)

Well, actually, if line fails, x is set to (1 1 0).  While it is true that
the value of the 3rd element of the list (if one exists) is ignored by the
rest of the function, this is rather sloppy coding.  Why not use an if
statement?  Ok, so it's more lines of code, but at least you can see at a
glance what is going on (and you avoid making silly logic mistakes like the
one above).

Now if you'll excuse me, I have to clean out my in box.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* A lighter read function
@ 1991-12-11  3:53 David J. Fiander
  0 siblings, 0 replies; 9+ messages in thread
From: David J. Fiander @ 1991-12-11  3:53 UTC (permalink / raw)
  To: The rc user community

Having seen, and been shocked at, the read example that comes
with the rc sources, I decided to try to write one that doesn't
require all of awk to run.  The following function provides
exactly the same functionality as the example source, except it
uses line(1) and doesn't do the assignment if the read fails.

nl='
'
fn read {
	x=() ifs=$nl {
		x = `{line || echo 1^$nl^1; echo 0} 
		if (~ $x(2) 0) $1 = $x(1)
		return $x(2)
	}
}

--
David J. Fiander   |email [Fr., = enamel] Used attrib. in `email ink', ink
<david@golem.uucp> |used on glass, porcelain, etc.


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~1991-12-13  2:11 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1991-12-11  4:32 A lighter read function DaviD W. Sanderson
1991-12-11 12:28 ` David J. Fiander
1991-12-11 19:28   ` Chris Siebenmann
1991-12-13  0:58     ` David J. Fiander
1991-12-13  1:37       ` Chris Siebenmann
1991-12-13  1:47       ` David Hogan
1991-12-11 21:48   ` Ronald S H Khoo
1991-12-12 12:16     ` David J. Fiander
  -- strict thread matches above, loose matches on Subject: below --
1991-12-11  3:53 David J. Fiander

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).