1/* seq.c - Count from first to last, by increment.
2 *
3 * Copyright 2006 Rob Landley <rob@landley.net>
4 *
5 * http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/seq.html
6
7USE_SEQ(NEWTOY(seq, "<1>3?f:s:", TOYFLAG_USR|TOYFLAG_BIN))
8
9config SEQ
10  bool "seq"
11  depends on TOYBOX_FLOAT
12  default y
13  help
14    usage: seq [-f fmt_str] [-s sep_str] [first] [increment] last
15
16    Count from first to last, by increment. Omitted arguments default
17    to 1. Two arguments are used as first and last. Arguments can be
18    negative or floating point.
19
20    -f	Use fmt_str as a floating point format string
21    -s	Use sep_str as separator, default is a newline character
22*/
23
24#define FOR_seq
25#include "toys.h"
26
27GLOBALS(
28  char *sep;
29  char *fmt;
30)
31
32void seq_main(void)
33{
34  double first, increment, last, dd;
35  char *sep_str = "\n";
36  char *fmt_str = "%g";
37  int output = 0;
38
39  // Parse command line arguments, with appropriate defaults.
40  // Note that any non-numeric arguments are treated as zero.
41  first = increment = 1;
42  switch (toys.optc) {
43    case 3: increment = atof(toys.optargs[1]);
44    case 2: first = atof(*toys.optargs);
45    default: last = atof(toys.optargs[toys.optc-1]);
46  }
47
48  if (toys.optflags & FLAG_f) fmt_str = TT.fmt;
49  if (toys.optflags & FLAG_s) sep_str = TT.sep;
50
51  // Yes, we're looping on a double.  Yes rounding errors can accumulate if
52  // you use a non-integer increment.  Deal with it.
53  for (dd=first; (increment>0 && dd<=last) || (increment<0 && dd>=last);
54    dd+=increment)
55  {
56    if (dd != first) printf("%s", sep_str);
57    printf(fmt_str, dd);
58    output = 1;
59  }
60
61  if (output) printf("\n");
62}
63