* [9fans] seq with hex, octal formats
@ 2010-02-27 19:01 erik quanstrom
2010-02-28 0:12 ` Russ Cox
0 siblings, 1 reply; 5+ messages in thread
From: erik quanstrom @ 2010-02-27 19:01 UTC (permalink / raw)
To: 9fans
[-- 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);
}' $*
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] seq with hex, octal formats
2010-02-27 19:01 [9fans] seq with hex, octal formats erik quanstrom
@ 2010-02-28 0:12 ` Russ Cox
2010-02-28 1:59 ` erik quanstrom
0 siblings, 1 reply; 5+ messages in thread
From: Russ Cox @ 2010-02-28 0:12 UTC (permalink / raw)
To: Fans of the OS Plan 9 from Bell Labs
diff -r 3024d1ef1140 src/cmd/seq.c
--- a/src/cmd/seq.c Wed Sep 30 11:01:45 2009 -0700
+++ b/src/cmd/seq.c Sat Feb 27 16:11:56 2010 -0800
@@ -47,6 +47,39 @@
format = fmt;
}
+extern int __ifmt(Fmt*); // _ifmt on Plan 9
+
+static int
+doifmt(Fmt *f, ...)
+{
+ int rv;
+ va_list argsav;
+
+ f->flags |= FmtVLong;
+ va_copy(argsav, f->args);
+ va_end(f->args);
+ va_start(f->args, f);
+ rv = __ifmt(f);
+ va_end(f->args);
+ va_copy(f->args, argsav);
+ va_end(argsav);
+ return rv;
+}
+
+static int
+ifmt(Fmt *f)
+{
+ int rv;
+ static int running;
+
+ if(running)
+ return __ifmt(f);
+ running = 1;
+ rv = doifmt(f, (vlong)va_arg(f->args, double));
+ running = 0;
+ return rv;
+}
+
void
main(int argc, char *argv[]){
int j, n;
@@ -79,7 +112,11 @@
fprint(2, "seq: zero increment\n");
exits("zero increment");
}
- if(!format)
+ if(format){
+ fmtinstall('d', ifmt);
+ fmtinstall('o', ifmt);
+ fmtinstall('x', ifmt);
+ }else
buildfmt();
if(incr > 0){
for(val = min; val <= max; val += incr){
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] seq with hex, octal formats
2010-02-28 0:12 ` Russ Cox
@ 2010-02-28 1:59 ` erik quanstrom
2010-02-28 2:07 ` Lyndon Nerenberg (VE6BBM/VE7TFX)
0 siblings, 1 reply; 5+ messages in thread
From: erik quanstrom @ 2010-02-28 1:59 UTC (permalink / raw)
To: 9fans
very nice!
one problem, ifmt can crash with the argument -f %g.
fomatting %g will mean that !running to be true when
calling ifmt, thus ifmt will try to va_arg a double cast to
vlong when formatting an integer:
/sys/src/libc/fmt/fltfmt.c:136: sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1);
/sys/src/libc/fmt/fltfmt.c:142: sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1);
/sys/src/libc/fmt/fltfmt.c:155: sprint(s1+NSIGNIF, "e%d", e-NSIGNIF+1);
(actually, on testing, this version spins rather than crashes
on plan 9:
; ps -a | grep 1308769
quanstro 1308769 1:30 0:00 28K Running 8.seqrsc -f %g 1 5
)
using awk is still faster, and more
fundamentally, avoids crashing on bogus
formats like %g%g.
(also, -w doesn't work with either version
with a %x format because 'e' is a valid hex
digit and not an exponent.)
- erik
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] seq with hex, octal formats
2010-02-28 1:59 ` erik quanstrom
@ 2010-02-28 2:07 ` Lyndon Nerenberg (VE6BBM/VE7TFX)
2010-02-28 2:15 ` erik quanstrom
0 siblings, 1 reply; 5+ messages in thread
From: Lyndon Nerenberg (VE6BBM/VE7TFX) @ 2010-02-28 2:07 UTC (permalink / raw)
To: 9fans
> using awk is still faster
For the curious and lazy ... why is that?
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [9fans] seq with hex, octal formats
2010-02-28 2:07 ` Lyndon Nerenberg (VE6BBM/VE7TFX)
@ 2010-02-28 2:15 ` erik quanstrom
0 siblings, 0 replies; 5+ messages in thread
From: erik quanstrom @ 2010-02-28 2:15 UTC (permalink / raw)
To: 9fans
On Sat Feb 27 21:08:17 EST 2010, lyndon@orthanc.ca wrote:
> > using awk is still faster
>
> For the curious and lazy ... why is that?
it is curious!
it appears that the ape strtod is much faster,
though it isn't quite correct:
both of these are in /sys/src/libc/port/strtod.c
% Time Calls Name
43.8 3.492 4385186 fpcmp
35.0 2.788 62445696 frnorm
- erik
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-02-28 2:15 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-02-27 19:01 [9fans] seq with hex, octal formats erik quanstrom
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
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).