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 
7 USE_SEQ(NEWTOY(seq, "<1>3?f:s:", TOYFLAG_USR|TOYFLAG_BIN))
8 
9 config 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 
GLOBALS(char * sep;char * fmt;)27 GLOBALS(
28   char *sep;
29   char *fmt;
30 )
31 
32 void 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