9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
From: erik quanstrom <quanstro@quanstro.net>
To: 9fans@9fans.net
Subject: [9fans] seq with hex, octal formats
Date: Sat, 27 Feb 2010 14:01:40 -0500	[thread overview]
Message-ID: <2dfd9898fe7656a885285032d9727684@ladd.quanstro.net> (raw)

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

i've attached a little program that extends
seq to print sequences in hex or octal.  for example,

	;  seq.rc -f %.4x 0x3b1 0x3b2
	03b1
	03b2

i did it in rc (really awk) because it was too tedious
to get the details right in c.

as such, formats are as in printf(2) not as in print(2).
this is a bug, but i don't see a reasonable workaround.

even using awk and adding functionality, the new
program is *way* faster than seq:

	; >/dev/null time seq 1 100000
	1.90u 0.09s 1.99r 	 seq 1 100000
	; >/dev/null time seq.rc 1 100000
	0.28u 0.00s 0.29r 	 seq.rc 1 100000

- erik

[-- Attachment #2: seq.rc --]
[-- Type: text/plain, Size: 2291 bytes --]

#!/bin/rc

awk '
function hex(s,        base, r, n, i, k, c)
{
	base = 16;
	if(s ~ /^0[xX][0-9a-fA-F]+/)
		s = substr(str, 3);
	n = length(s)
  	r = 0
	for (i = 1; i <= n; i++) {
		c = tolower(substr(s, i, 1))
		k = index("0123456789abcdef", c) - 1;
		r = r * base + k
	}
     	return r
}

function mystrtonum(str0,        neg, base, str, r, n, i, k, c)
{
	base = 0;
	neg = 0;
	str = str0;
	if(str ~ /^\+/)
		str = substr(str, 2)
	if(str ~ /^-/){
		str = substr(str, 2)
		neg = 1
	}
	if(str ~ /^0[0-7]*$/)
		base = 8
	if(str ~ /^0[xX][0-9a-fA-F]+/){
		str = substr(str, 3);
		base = 16;
	}
	if(base != 0){
		n = length(str)
  		r = 0
		for (i = 1; i <= n; i++) {
			c = tolower(substr(str, i, 1))
			k = index("0123456789abcdef", c) - 1;
			r = r * base + k
		}
	}else if(str ~ /^[0-9]*([.][0-9]*)?([Ee][-+]?[0-9]+)?$/)
		r = str0 + 0
	else
		r = "NaN"
     	return r
}

function usage()
{
	print "usage: seq [-w] [-f fmt] min [inc] max" > "/fd/2"
	exit(1);
}

function EARGF()
{
	if(j + 1 < length(a))
		return substr(a, j+1, 100);
	i++;
	if(i >= ARGC)
		usage();
	return ARGV[i];
}

function args()
{
	for(i = 1; i < ARGC; i++){
		a = ARGV[i]
		if(a !~ /^-..*/)
			break;
		for(j = 2; j <= length(a); j++){
			c = substr(a, j, 1);
			if(c == "w")
				flagw = 1
			else if(c == "f"){
				format = EARGF()
				if(format !~ /\n$/)
					format = format "\n"
			}else
				usage()
		}
	}
	n = ARGC - i
	if(n != 2 && n != 3)
		usage()
	min = mystrtonum(ARGV[i++])
	incr = 1
	if(n == 3)
		incr = mystrtonum(ARGV[i++])
	max = mystrtonum(ARGV[i++])
}

function buildfmt()
{
	if(length(format) > 0)
		return;
	format = "%g\n";
	if(!flagw)
		return;
	maxw = 0;
	maxp = 0;
	for(val = min; val <= max; val += incr){
		buf = sprintf("%g", val)
		if(buf ~ /e/)
			return
		parts = split(buf, ary, "\.");
		w = length(ary[1]);
		p = length(ary[2]) + parts==2;
		if(w>maxw)
			maxw = w;
		if(p>maxp)
			maxp = p;
	}
	if(maxp > 0)
		maxw += maxp+1;
	format = sprintf("%%0%d.%df\n", maxw, maxp);
}

BEGIN{
	args();
	buildfmt()

	for(val = min;; val += incr){
		if(incr > 0 && val > max)
			break;
		if(incr < 0 && val < max)
			break;
		printf(format, val)
	}

	exit(0);
}' $*

             reply	other threads:[~2010-02-27 19:01 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-27 19:01 erik quanstrom [this message]
2010-02-28  0:12 ` Russ Cox
2010-02-28  1:59   ` erik quanstrom
2010-02-28  2:07     ` Lyndon Nerenberg (VE6BBM/VE7TFX)
2010-02-28  2:15       ` erik quanstrom

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=2dfd9898fe7656a885285032d9727684@ladd.quanstro.net \
    --to=quanstro@quanstro.net \
    --cc=9fans@9fans.net \
    /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).