9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: "andrey mirtchovski" <mirtchovski@gmail.com>
To: "jmk@plan9.bell-labs.com" <jmk@plan9.bell-labs.com>,
	"Fans of the OS Plan 9 from Bell Labs" <9fans@cse.psu.edu>
Subject: [9fans] Re: "grep" and "grep -v"
Date: Fri, 22 Jun 2007 11:51:25 -0600	[thread overview]
Message-ID: <14ec7b180706221051r398b72cdga7712c8afa3b18c2@mail.gmail.com> (raw)
In-Reply-To: <a94c19694e416db4c59b08169b079081@plan9.bell-labs.com>

[-- Attachment #1: Type: text/plain, Size: 570 bytes --]

On 6/20/07, jmk@plan9.bell-labs.com <jmk@plan9.bell-labs.com> wrote:
> current problem is, given an ip address, say 135.104.9.7
> and an ip mask, say 255.255.255.0,how do i get the result
> of addr & mask using only sed and echo?
>

sitting idly at usenix, not listening to the boring talks. it can be
done, but it's not pretty. hope you don't mind the 36 seconds it takes
to compute:

parr% date; andip 123.124.125.126 255.255.0.127; date
Fri Jun 22 13:43:48 EDT 2007
123.124.0.126
Fri Jun 22 13:44:24 EDT 2007
parr%

now i think i'll go to the beach.

[-- Attachment #2: jmk.txt --]
[-- Type: text/plain, Size: 5532 bytes --]

####################
# helper functions #
####################
fn mshift {
	shift
	echo $*
}


fn reverse {
	switch($#*) {
	case 1
		echo $1
	case *
		echo `{reverse `{mshift $*}} $1
	}
}

fn split {
	n = $1
	shift
	if(~ $n '') {
		echo $* | sed 's/(.)/\1 /g'
	}
	if not{
		echo $* | sed 's/'^$n^'/ /g'
	}
}

fn join {
	echo $* | sed 's/ //g'
}

fn length {
	echo $#*
}

fn pad {
}
####################

fn and1 {
	switch($#*) {
	case 2
		if(~ $1 1 && ~ $2 1) {
			echo 1
		}
		if not{
			echo 0
		}
	case 1
		echo NaN
	}
}

fn and {
	{
		switch($#*) {
		case 2
			n = (`{split '' $2})
			* = (`{split '' $1})
			while(! ~ $#* 0) {
				echo -n `{and1 $1 $n(1)}^' '
				shift
				n = `{mshift $n}
			}	
		}

	}| sed 's/ $//;s/ //g'
}

fn or1 {
	switch($#*) {
	case 2
		if(~ $1 0 && ~ $2 0) {
			echo 0
		}
		if not{
			echo 1
		}
	}
}

fn or {
	{
		switch($#*) {
		case 2
			n = (`{split '' $2})
			* = (`{split '' $1})
			while(! ~ $#* 0) {
				echo -n `{or1 $1 $n(1)}^' '
				shift
				n = `{mshift $n}
			}	
		}

	}| sed 's/ $//;s/ //g'
}

fn cmp1 {
	n = ''
	switch($1) {
	case 0
		switch($2) {
		case 0
			n = 0
		case 1
			n = 1
		}
	case 1
		switch($2) {
		case 0
			n = -1
		case 1
			n = 0
		}
	case *
		n = NaN
	}	
	echo $n	
}

fn cmpb {
	res = 0
	switch($#*) {
	case 2
		one = `{split '' $1}
		two = `{split '' $2}
		if(~ $#one $#two) {
			while(! ~ $#one 0 && ~ $res 0) {
				res = `{cmp1 $one(1) $two(1)}
				one = `{mshift $one}
				two = `{mshift $two}
			}
			echo $res
		}
		if not {
			while(! ~ $#one 0 && ! ~ $#two 0) {
				one = `{mshift $one}
				two = `{mshift $two}
			}
			if(! ~ $#one 0) {
				echo -1
			}
			if not {
				echo 1
			}
		}
	}
}

fn cmp {
	switch($#*) {
	case 2
		cmpb `{tobin $1} `{tobin $2}
	}
}

fn modtwo1 {
	switch ($1) {
	case 2 4 6 8 0
		n = 0
	case 1 3 5 7 9
		n = 1
	case *
		n = NaN
	}
	echo $n
}
fn modtwo-long {
	n = $*
	modtwo1 $n($#n)
}

fn modtwo {
	modtwo-long `{split '' $1}
}

fn divtwo1 {
	switch ($1) {
	case 0
		n = 0
	case 1
		n = (0 1)
	case 2
		n = 1
	case 3
		n = (1 1)
	case 4
		n = 2
	case 5
		n = (2 1)
	case 6
		n = 3
	case 7
		n = (3 1)
	case 8
		n = 4
	case 9
		n = (4 1)
	case 10
		n = 5
	case 11
		n = (5 1)
	case 12
		n = 6
	case 13
		n = (6 1)
	case 14
		n = 7
	case 15
		n = (7 1)
	case 16
		n = 8
	case 17
		n = (8 1)
	case 18
		n = 9
	case 19
		n = (9 1)
	}
	echo $n
}

fn divtwo-long {
	switch($#*) {
	case 1
		n = (`{divtwo1 $1})
		echo $n(1)
	case *
		n = (`{divtwo1 $1})
		switch($#n) {
		case 1
			echo $n(1)  `{divtwo-long `{mshift $*}}
		case 2
			z = (`{mshift $*})
			echo $n(1)  `{divtwo-long $n(2)^$z(1) `{mshift $z}}
		}
	}
}

fn divtwo {
	divtwo-long `{split '' $1} |sed 's/ //g;s/^0+(.+)/\1/'
}

fn addone1 {
	switch ($1) {
	case 0
		n = 1
	case 1
		n = 2
	case 2
		n = 3
	case 3
		n = 4
	case 4
		n = 5
	case 5
		n = 6
	case 6
		n = 7
	case 7
		n = 8
	case 8
		n = 9
	case 9
		n = (0 1)
	case *
		n = NaN
	}
	echo $n
}

fn addone-long {
	# big-endian
	z = `{split '' $1}
	switch($#*) {
	case 1
		n = (`{addone1 $z})
		switch($#n) {
		case 1
			echo $n `{mshift $*}
		case 2
			echo $n(1) $n(2)
		}
	case *
		n = `{addone1 $z}
		switch($#n) {
		case 1
			echo -n $n(1) `{mshift $*}
		case 2
			nz = `{mshift $*}
			echo -n $n(1)  `{addone-long $nz(1)^$n(2) `{mshift $nz}}
		}
	}
}

fn addone {
	join `{reverse `{addone-long `{reverse `{split '' $1}}}}
}

fn multwo1 {
	switch ($1) {
	case 0
		n = 0
	case 1
		n = 2
	case 2
		n = 4
	case 3
		n = 6
	case 4
		n = 8
	case 5
		n = (0 1)
	case 6
		n = (2 1)
	case 7
		n = (4 1)
	case 8
		n = (6 1)
	case 9
		n = (8 1)
	}

	if(~ $#* 2) {
		switch($#n) {
		case 2
			n = (`{addone1 $n(1)} $n(2))
		case 1
			n = `{addone $n}
		}
	}
	echo $n
}

fn multwo-long {
	# big-endian
	z = `{split '' $1}
	switch($#*) {
	case 1
		n = `{multwo1 $z}
		switch($#n) {
		case 1
			echo $n
		case 2
			echo $n(1) $n(2)
		}
	case *
		n = `{multwo1 $z}
		nn = `{mshift $*}
		switch($#n) {
		case 1
			echo $n `{multwo-long $nn}
		case 2
			echo $n(1)  `{multwo-long $nn(1)^$n(2) `{mshift $nn}}
		}
	}
}

fn multwo {
	join `{reverse `{multwo-long `{reverse `{split '' $1}}}}
}

fn tobin-long {
	n = `{divtwo $1}
	if(! ~ $n 0) {
		echo -n `{tobin-long `{divtwo $1}} `{modtwo $1}
	} 
	if not {
		modtwo $1
	}
}

fn tobin {
	join `{tobin-long $1}
}

fn padb {
	# pad the first binary number with zeros until 
	# it becomes as long as the second
	# 
	# user must ensure that the first argument is 
	# numerically less than the second

	one = `{split '' $1}
	two = `{split '' $2}

	while(! ~ $#one $#two) {
		one = ('0' $one)
	}
	echo `{join $one}
}

fn todec-long {
	# rear-endian
	switch ($#*) {
	case 1
		switch($1) {
		case 1
			echo -n 1
		case *
			echo -n NaN	# can not end with a zero
		}
	case *
		switch ($1) {
		case 0
			multwo `{todec-long `{mshift $*} }
		case 1
			addone `{multwo `{todec-long `{mshift $*} } }
		}
	}
}

fn todec {
	switch($1) {
	case 0
		echo 0
	case *
		join `{reverse `{todec-long `{reverse `{split '' $1}}}}
	}
}

####################################################
fn andip1 {
	switch($#*) {
	case 2
		ns = `{tobin $1}
		nn = `{tobin $2}
		switch(`{cmpb $nn $ns}) {
		case -1
			ns = `{padb $ns $nn}
		case 1
			nn = `{padb $nn $ns}
		}
		r = `{and $ns $nn}
		todec `{echo $r |sed 's/^0+(.+)$/\1/'}
	case *
		echo NaN
	}	
}
fn andip {
	{
		n = (`{split '\.' $2 })
		* = (`{split '\.' $1 })
		if(~ $#n $#*) {
			while(! ~ $#* 0) {
				echo -n `{andip1 $n(1) $1}^' '
				shift
				n = `{mshift $n}
			}
		}
		if not {
			echo 'number of quads must match'
		}
	}| sed 's/ $//;s/ /./g'
}

       reply	other threads:[~2007-06-22 17:51 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <14ec7b180706201440j5628ed3em693c3f7222f86a14@mail.gmail.com>
     [not found] ` <a94c19694e416db4c59b08169b079081@plan9.bell-labs.com>
2007-06-22 17:51   ` andrey mirtchovski [this message]
2007-06-22 21:05     ` ron minnich

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=14ec7b180706221051r398b72cdga7712c8afa3b18c2@mail.gmail.com \
    --to=mirtchovski@gmail.com \
    --cc=9fans@cse.psu.edu \
    --cc=jmk@plan9.bell-labs.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).