aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/seq.c
blob: 062bb8a4a9635ed19807e6ff864c9a3963ac4958 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <u.h>
#include <libc.h>

double	min = 1.0;
double	max = 0.0;
double	incr = 1.0;
int	constant = 0;
int	nsteps;
char	*format;

void
usage(void)
{
	fprint(2, "usage: seq [-fformat] [-w] [first [incr]] last\n");
	exits("usage");
}

void
buildfmt(void)
{
	int i;
	char *dp;
	int w, p, maxw, maxp;
	static char fmt[16];
	char buf[32];

	format = "%g\n";
	if(!constant)
		return;
	maxw = 0;
	maxp = 0;
	for(i=0; i<=nsteps; i++){
		sprint(buf, "%g", min+i*incr);
		if(strchr(buf, 'e')!=0)
			return;
		dp = strchr(buf,'.');
		w = dp==0? strlen(buf): dp-buf;
		p = dp==0? 0: strlen(strchr(buf,'.')+1);
		if(w>maxw)
			maxw = w;
		if(p>maxp)
			maxp = p;
	}
	if(maxp > 0)
		maxw += maxp+1;
	sprint(fmt,"%%%d.%df\n", maxw, maxp);
	format = fmt;
}

void
main(int argc, char *argv[]){
	int i, j, n;
	char buf[256], ffmt[4096];

	ARGBEGIN{
	case 'w':
		constant++;
		break;
	case 'f':
		format = ARGF();
		if(format[strlen(format)-1] != '\n'){
			sprint(ffmt, "%s\n", format);
			format = ffmt;
		}
		break;
	default:
		goto out;
	}ARGEND
    out:
	if(argc<1 || argc>3)
		usage();
	max = atof(argv[argc-1]);
	if(argc > 1)
		min = atof(argv[0]);
	if(argc > 2)
		incr = atof(argv[1]);
	if(incr == 0){
		fprint(2, "seq: zero increment\n");
		exits("zero increment");
	}
	nsteps = (max-min)/incr+.5;
	if(!format)
		buildfmt();
	for(i=0; i<=nsteps; i++){
		n = sprint(buf, format, min+i*incr);
		if(constant)
			for(j=0; buf[j]==' '; j++)
				buf[j] ='0';
		write(1, buf, n);
	}
	exits(0);
}