SlideShare a Scribd company logo
1 of 25
Specification of the "sequ" command
Copyright © 2013 Bart Massey
Revision 0: 1 October 2013
This specification describes the "universal sequence" command
sequ. The sequ command is a backward-compatible set of
extensions to the UNIX
[seq](http://www.gnu.org/software/coreutils/manual/html_node/
seq-invocation.html) command. There are many
implementations of seq out there: this specification is built on
the seq supplied with GNU Coreutils version 8.21.
The seq command emits a monotonically increasing sequence of
numbers. It is most commonly used in shell scripting:
TOTAL=0
for i in `seq 1 10`
do
TOTAL=`expr $i + $TOTAL`
done
echo $TOTAL
prints 55 on standard output. The full sequ command does this
basic counting operation, plus much more.
This specification of sequ is in several stages, known as
compliance levels. Each compliance level adds required
functionality to the sequ specification. Level 1 compliance is
equivalent to the Coreutils seq command.
The usual specification language applies to this document:
MAY, SHOULD, MUST (and their negations) are used in the
standard fashion.
Wherever the specification indicates an error, a conforming
sequ implementation MUST immediately issue appropriate error
message specific to the problem. The implementation then
MUST exit, with a status indicating failure to the invoking
process or system. On UNIX systems, the error MUST be
indicated by exiting with status code 1.
When a conforming sequ implementation successfully completes
its output, it MUST immediately exit, with a status indicating
success to the invoking process or systems. On UNIX systems,
success MUST be indicated by exiting with status code 0.
Compliance Level 0
Compliance Level 0 of sequ requires absolute minimum
functionality. A CL0 sequ MUST accept exactly two command-
line arguments. Each argument SHOULD be a representation of
an integer value. Any other supplied argument syntax is an
error.
If the first integer argument is numerically greater than the
second, the sequ command MUST emit no output. Otherwise,
sequ MUST print on its output each of the integers between the
first and second argument, inclusive. Each output integer MUST
be on a line by itself, that is, a line terminated with an
appropriate line terminator for the host environment.
Compliance Level 1
Compliance Level 1 of sequ adds the full functionality of GNU
Coreutils seq. This includes the "--format", "--separator", "--
equal-width", "--help" and "--version" arguments (as well as the
one-character abbreviations of these), the increment argument,
and support for floating-point numbers. The sequ initialization
and increment arguments are now optional, as per the seq spec.
The sequ "--format" specifier MAY format floating-point
numbers differently than seq, but it MUST follow some well-
described and reasonable floating-point formatting standard.
Backslash-escapes in the "-s" argument string MUST be
processed as in C printf(3).
Start a text file of notes on what you're about to do. As you
work on this assignment, make notes about you findings and
progress. You will turn in your notes at the end.
Read CL1 of the sequ spec. Note down any questions and
concerns you have about it.
Write tests for CL1 of sequ. Be sure to have enough tests to
catch problems with your implementation.
Write pseudocode for any parts of CL1 of sequ that you think
need it. Check your pseudocode into the repo.
Write CL1 of sequ. Verify that it passes your tests. Record test
results and debugging steps in your notes.
Compliance Level 2
Compliance Level 2 of sequ adds additional convenience
arguments for formatting.
The arguments that MUST be accepted are as follows:
-W, --words: Output the sequence as a single space-separated
line. Equivalent to "-s ' '".
-p, --pad : Output the sequence with elements padded on the left
to be all of equal width: the pad character is given by the
single-char pad string . Backslash-escapes in MUST be
processed as in C printf(3).
Note that the "-w" command of level 2 is equivalent to "-p '0'".
-P, --pad-spaces: Output the sequence with elements padded
with spaces on the left to be all of equal width. Equivalent to "-
p ' '".
Compliance Level 3
Compliance Level 3 of sequ adds the ability to have sequences
of types other than floating-point numbers.
Specifically, CL3 sequ MUST accept as arguments and output
as results: arbitrary-precision integers, single lowercase
alphabetic (ASCII) letters, single uppercase alphabetic (ASCII)
letters, and lowercase or uppercase unsigned Roman Numerals.
The sequ command MUST accept a new flag, "--format-word"
or "-F", that takes a one-word argument indicating the type of
the sequence. The sequ command MUST accept the format-word
arguments "arabic" (for integers), "floating", "alpha" (for
letters), "ALPHA", "roman" or "ROMAN"; the all-uppercase
variants indicate uppercase sequences.
The sequ command MUST accept limit arguments (start, end,
and increment) in the format consistent with the format-word.
Arabic limit arguments MAY be "promoted" to Roman
Numerals when Roman output is requested. The increment
argument for alpha formats MUST be arabic. Otherwise, the
limit arguments MUST be in the same format as the format-
word. When no format-word is given, the format MUST be
inferred from the format of the mandatory end argument.
Compliance Level 4
Compliance Level 4 of sequ adds the ability to number the lines
of a textfile presented on the input.
CL4 sequ MUST accept the "--number-lines" / "-n" argument.
This argument indicates that, rather than outputting the
sequence on standard output, sequ will act as a filter, numbering
lines of a file read from standard input to standard output. Each
line "number" will be in the format specified by the "--format-
word" argument, or inferred from the start or increment limit
argument if the "--format-word" argument is not supplied. The
end argument is irrelevant when "--number-lines" is supplied; it
MUST NOT be accepted. The separator between the line number
and the line may be given by the "--separator" argument,
defaulting to space.
Compliance Level 5
Compliance Level 5 of sequ adds the ability to infer a sequence
from a given prefix.
As an alternative to the limit arguments of previous Compliance
Levels, CL5 sequ may accept a sequence specifier of the form:
value [value] [value] ... ".." value
When the ".." argument is present, the non-flag arguments
MUST be parsed in inference mode.
In inference mode, sequ picks a best match for the pattern
(partial sequence of values leading up to the ".."), and then
continues the sequence until the end value (after the "..") is
succeeded.
/* seq - print sequence of numbers to standard output.
Copyright (C) 1994-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or
modify
it under the terms of the GNU General Public License as
published by
the Free Software Foundation, either version 3 of the License,
or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied
warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public
License
along with this program. If not, see
<http://www.gnu.org/licenses/>. */
/* Written by Ulrich Drepper. */
#include <config.h>
#include <getopt.h>
#include <stdio.h>
#include <sys/types.h>
#include "system.h"
#include "c-strtod.h"
#include "error.h"
#include "quote.h"
#include "xstrtod.h"
/* Roll our own isfinite rather than using <math.h>, so that we
don't
have to worry about linking -lm just for isfinite. */
#ifndef isfinite
# define isfinite(x) ((x) * 0 == 0)
#endif
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "seq"
#define AUTHORS proper_name ("Ulrich Drepper")
/* If true print all number with equal width. */
static bool equal_width;
/* The string used to separate two numbers. */
static char const *separator;
/* The string output after all numbers have been output.
Usually "n" or "0". */
static char const terminator[] = "n";
static struct option const long_options[] =
{
{ "equal-width", no_argument, NULL, 'w'},
{ "format", required_argument, NULL, 'f'},
{ "separator", required_argument, NULL, 's'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{ NULL, 0, NULL, 0}
};
void
usage (int status)
{
if (status != EXIT_SUCCESS)
emit_try_help ();
else
{
printf (_("
Usage: %s [OPTION]... LASTn
or: %s [OPTION]... FIRST LASTn
or: %s [OPTION]... FIRST INCREMENT LASTn
"), program_name, program_name, program_name);
fputs (_("
Print numbers from FIRST to LAST, in steps of
INCREMENT.n
"), stdout);
emit_mandatory_arg_note ();
fputs (_("
-f, --format=FORMAT use printf style floating-point
FORMATn
-s, --separator=STRING use STRING to separate numbers
(default: n)n
-w, --equal-width equalize width by padding with leading
zeroesn
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("
n
If FIRST or INCREMENT is omitted, it defaults to 1. That is,
ann
omitted INCREMENT defaults to 1 even when LAST is smaller
than FIRST.n
The sequence of numbers ends when the sum of the current
number andn
INCREMENT would become greater than LAST.n
FIRST, INCREMENT, and LAST are interpreted as floating
point values.n
INCREMENT is usually positive if FIRST is smaller than
LAST, andn
INCREMENT is usually negative if FIRST is greater than
LAST.n
"), stdout);
fputs (_("
FORMAT must be suitable for printing one argument of type
'double';n
it defaults to %.PRECf if FIRST, INCREMENT, and LAST are
all fixed pointn
decimal numbers with maximum precision PREC, and to %g
otherwise.n
"), stdout);
emit_ancillary_info ();
}
exit (status);
}
/* A command-line operand. */
struct operand
{
/* Its value, converted to 'long double'. */
long double value;
/* Its print width, if it were printed out in a form similar to its
input form. An input like "-.1" is treated like "-0.1", and an
input like "1." is treated like "1", but otherwise widths are
left alone. */
size_t width;
/* Number of digits after the decimal point, or INT_MAX if
the
number can't easily be expressed as a fixed-point number. */
int precision;
};
typedef struct operand operand;
/* Description of what a number-generating format will
generate. */
struct layout
{
/* Number of bytes before and after the number. */
size_t prefix_len;
size_t suffix_len;
};
/* Read a long double value from the command line.
Return if the string is correct else signal error. */
static operand
scan_arg (const char *arg)
{
operand ret;
if (! xstrtold (arg, NULL, &ret.value, c_strtold))
{
error (0, 0, _("invalid floating point argument: %s"), arg);
usage (EXIT_FAILURE);
}
/* We don't output spaces or '+' so don't include in width */
while (isspace (to_uchar (*arg)) || *arg == '+')
arg++;
ret.width = strlen (arg);
ret.precision = INT_MAX;
if (! arg[strcspn (arg, "xX")] && isfinite (ret.value))
{
char const *decimal_point = strchr (arg, '.');
if (! decimal_point)
ret.precision = 0;
else
{
size_t fraction_len = strcspn (decimal_point + 1, "eE");
if (fraction_len <= INT_MAX)
ret.precision = fraction_len;
ret.width += (fraction_len == 0 /* #. -> #
*/
? -1
: (decimal_point == arg /* .# -> 0.#
*/
|| ! ISDIGIT (decimal_point[-1]))); /* -.# ->
0.# */
}
char const *e = strchr (arg, 'e');
if (! e)
e = strchr (arg, 'E');
if (e)
{
long exponent = strtol (e + 1, NULL, 10);
ret.precision += exponent < 0 ? -exponent : 0;
/* Don't account for e.... in the width since this is not
output. */
ret.width -= strlen (arg) - (e - arg);
/* Adjust the width as per the exponent. */
if (exponent < 0)
{
if (decimal_point)
{
if (e == decimal_point + 1) /* undo #. -> # above
*/
ret.width++;
}
else
ret.width++;
exponent = -exponent;
}
ret.width += exponent;
}
}
return ret;
}
/* If FORMAT is a valid printf format for a double argument,
return
its long double equivalent, allocated from dynamic storage,
and
store into *LAYOUT a description of the output layout;
otherwise,
report an error and exit. */
static char const *
long_double_format (char const *fmt, struct layout *layout)
{
size_t i;
size_t prefix_len = 0;
size_t suffix_len = 0;
size_t length_modifier_offset;
bool has_L;
for (i = 0; ! (fmt[i] == '%' && fmt[i + 1] != '%'); i += (fmt[i]
== '%') + 1)
{
if (!fmt[i])
error (EXIT_FAILURE, 0,
_("format %s has no %% directive"), quote (fmt));
prefix_len++;
}
i++;
i += strspn (fmt + i, "-+#0 '");
i += strspn (fmt + i, "0123456789");
if (fmt[i] == '.')
{
i++;
i += strspn (fmt + i, "0123456789");
}
length_modifier_offset = i;
has_L = (fmt[i] == 'L');
i += has_L;
if (fmt[i] == '0')
error (EXIT_FAILURE, 0, _("format %s ends in %%"), quote
(fmt));
if (! strchr ("efgaEFGA", fmt[i]))
error (EXIT_FAILURE, 0,
_("format %s has unknown %%%c directive"), quote
(fmt), fmt[i]);
for (i++; ; i += (fmt[i] == '%') + 1)
if (fmt[i] == '%' && fmt[i + 1] != '%')
error (EXIT_FAILURE, 0, _("format %s has too many %%
directives"),
quote (fmt));
else if (fmt[i])
suffix_len++;
else
{
size_t format_size = i + 1;
char *ldfmt = xmalloc (format_size + 1);
memcpy (ldfmt, fmt, length_modifier_offset);
ldfmt[length_modifier_offset] = 'L';
strcpy (ldfmt + length_modifier_offset + 1,
fmt + length_modifier_offset + has_L);
layout->prefix_len = prefix_len;
layout->suffix_len = suffix_len;
return ldfmt;
}
}
/* Actually print the sequence of numbers in the specified
range, with the
given or default stepping and format. */
static void
print_numbers (char const *fmt, struct layout layout,
long double first, long double step, long double last)
{
bool out_of_range = (step < 0 ? first < last : last < first);
if (! out_of_range)
{
long double x = first;
long double i;
for (i = 1; ; i++)
{
long double x0 = x;
printf (fmt, x);
if (out_of_range)
break;
x = first + i * step;
out_of_range = (step < 0 ? x < last : last < x);
if (out_of_range)
{
/* If the number just past LAST prints as a value equal
to LAST, and prints differently from the previous
number, then print the number. This avoids
problems
with rounding. For example, with the x86 it causes
"seq 0 0.000001 0.000003" to print 0.000003 instead
of stopping at 0.000002. */
bool print_extra_number = false;
long double x_val;
char *x_str;
int x_strlen;
setlocale (LC_NUMERIC, "C");
x_strlen = asprintf (&x_str, fmt, x);
setlocale (LC_NUMERIC, "");
if (x_strlen < 0)
xalloc_die ();
x_str[x_strlen - layout.suffix_len] = '0';
if (xstrtold (x_str + layout.prefix_len, NULL, &x_val,
c_strtold)
&& x_val == last)
{
char *x0_str = NULL;
if (asprintf (&x0_str, fmt, x0) < 0)
xalloc_die ();
print_extra_number = !STREQ (x0_str, x_str);
free (x0_str);
}
free (x_str);
if (! print_extra_number)
break;
}
fputs (separator, stdout);
}
fputs (terminator, stdout);
}
}
/* Return the default format given FIRST, STEP, and LAST. */
static char const *
get_default_format (operand first, operand step, operand last)
{
static char format_buf[sizeof "%0.Lf" + 2 *
INT_STRLEN_BOUND (int)];
int prec = MAX (first.precision, step.precision);
if (prec != INT_MAX && last.precision != INT_MAX)
{
if (equal_width)
{
/* increase first_width by any increased precision in step
*/
size_t first_width = first.width + (prec - first.precision);
/* adjust last_width to use precision from first/step */
size_t last_width = last.width + (prec - last.precision);
if (last.precision && prec == 0)
last_width--; /* don't include space for '.' */
if (last.precision == 0 && prec)
last_width++; /* include space for '.' */
if (first.precision == 0 && prec)
first_width++; /* include space for '.' */
size_t width = MAX (first_width, last_width);
if (width <= INT_MAX)
{
int w = width;
sprintf (format_buf, "%%0%d.%dLf", w, prec);
return format_buf;
}
}
else
{
sprintf (format_buf, "%%.%dLf", prec);
return format_buf;
}
}
return "%Lg";
}
/* The NUL-terminated string S0 of length S_LEN represents a
valid
non-negative decimal integer. Adjust the string and length so
that the pair describe the next-larger value. */
static void
incr (char **s0, size_t *s_len)
{
char *s = *s0;
char *endp = s + *s_len - 1;
do
{
if ((*endp)++ < '9')
return;
*endp-- = '0';
}
while (endp >= s);
*--(*s0) = '1';
++*s_len;
}
/* Compare A and B (each a NUL-terminated digit string), with
lengths
given by A_LEN and B_LEN. Return +1 if A < B, -1 if B <
A, else 0. */
static int
cmp (char const *a, size_t a_len, char const *b, size_t b_len)
{
if (a_len < b_len)
return -1;
if (b_len < a_len)
return 1;
return (strcmp (a, b));
}
/* Trim leading 0's from S, but if S is all 0's, leave one.
Return a pointer to the trimmed string. */
static char const * _GL_ATTRIBUTE_PURE
trim_leading_zeros (char const *s)
{
char const *p = s;
while (*s == '0')
++s;
/* If there were only 0's, back up, to leave one. */
if (!*s && s != p)
--s;
return s;
}
/* Print all whole numbers from A to B, inclusive -- to stdout,
each
followed by a newline. If B < A, return false and print
nothing.
Otherwise, return true. */
static bool
seq_fast (char const *a, char const *b)
{
/* Skip past any leading 0's. Without this, our naive cmp
function would declare 000 to be larger than 99. */
a = trim_leading_zeros (a);
b = trim_leading_zeros (b);
size_t p_len = strlen (a);
size_t q_len = strlen (b);
size_t n = MAX (p_len, q_len);
char *p0 = xmalloc (n + 1);
char *p = memcpy (p0 + n - p_len, a, p_len + 1);
char *q0 = xmalloc (n + 1);
char *q = memcpy (q0 + n - q_len, b, q_len + 1);
bool ok = cmp (p, p_len, q, q_len) <= 0;
if (ok)
{
/* Buffer at least this many numbers per fwrite call.
This gives a speed-up of more than 2x over the
unbuffered code
when printing the first 10^9 integers. */
enum {N = 40};
char *buf = xmalloc (N * (n + 1));
char const *buf_end = buf + N * (n + 1);
char *z = buf;
/* Write first number to buffer. */
z = mempcpy (z, p, p_len);
/* Append separator then number. */
while (cmp (p, p_len, q, q_len) < 0)
{
*z++ = *separator;
incr (&p, &p_len);
z = mempcpy (z, p, p_len);
/* If no place for another separator + number then
output buffer so far, and reset to start of buffer. */
if (buf_end - (n + 1) < z)
{
fwrite (buf, z - buf, 1, stdout);
z = buf;
}
}
/* Write any remaining buffered output, and the terminator.
*/
*z++ = *terminator;
fwrite (buf, z - buf, 1, stdout);
IF_LINT (free (buf));
}
free (p0);
free (q0);
return ok;
}
/* Return true if S consists of at least one digit and no non-
digits. */
static bool _GL_ATTRIBUTE_PURE
all_digits_p (char const *s)
{
size_t n = strlen (s);
return ISDIGIT (s[0]) && n == strspn (s, "0123456789");
}
int
main (int argc, char **argv)
{
int optc;
operand first = { 1, 1, 0 };
operand step = { 1, 1, 0 };
operand last;
struct layout layout = { 0, 0 };
/* The printf(3) format used for output. */
char const *format_str = NULL;
initialize_main (&argc, &argv);
set_program_name (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
atexit (close_stdout);
equal_width = false;
separator = "n";
/* We have to handle negative numbers in the command line
but this
conflicts with the command line arguments. So explicitly
check first
whether the next argument looks like a negative number. */
while (optind < argc)
{
if (argv[optind][0] == '-'
&& ((optc = argv[optind][1]) == '.' || ISDIGIT (optc)))
{
/* means negative number */
break;
}
optc = getopt_long (argc, argv, "+f:s:w", long_options,
NULL);
if (optc == -1)
break;
switch (optc)
{
case 'f':
format_str = optarg;
break;
case 's':
separator = optarg;
break;
case 'w':
equal_width = true;
break;
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME,
AUTHORS);
default:
usage (EXIT_FAILURE);
}
}
unsigned int n_args = argc - optind;
if (n_args < 1)
{
error (0, 0, _("missing operand"));
usage (EXIT_FAILURE);
}
if (3 < n_args)
{
error (0, 0, _("extra operand %s"), quote (argv[optind +
3]));
usage (EXIT_FAILURE);
}
if (format_str)
format_str = long_double_format (format_str, &layout);
if (format_str != NULL && equal_width)
{
error (0, 0, _("format string may not be specified"
" when printing equal width strings"));
usage (EXIT_FAILURE);
}
/* If the following hold:
- no format string, [FIXME: relax this, eventually]
- integer start (or no start)
- integer end
- increment == 1 or not specified [FIXME: relax this,
eventually]
then use the much more efficient integer-only code. */
if (all_digits_p (argv[optind])
&& (n_args == 1 || all_digits_p (argv[optind + 1]))
&& (n_args < 3 || (STREQ ("1", argv[optind + 1])
&& all_digits_p (argv[optind + 2])))
&& !equal_width && !format_str && strlen (separator) ==
1)
{
char const *s1 = n_args == 1 ? "1" : argv[optind];
char const *s2 = argv[optind + (n_args - 1)];
if (seq_fast (s1, s2))
exit (EXIT_SUCCESS);
/* Upon any failure, let the more general code deal with it.
*/
}
last = scan_arg (argv[optind++]);
if (optind < argc)
{
first = last;
last = scan_arg (argv[optind++]);
if (optind < argc)
{
step = last;
last = scan_arg (argv[optind++]);
}
}
if (first.precision == 0 && step.precision == 0 &&
last.precision == 0
&& 0 <= first.value && step.value == 1 && 0 <= last.value
&& !equal_width && !format_str && strlen (separator) ==
1)
{
char *s1;
char *s2;
if (asprintf (&s1, "%0.Lf", first.value) < 0)
xalloc_die ();
if (asprintf (&s2, "%0.Lf", last.value) < 0)
xalloc_die ();
if (seq_fast (s1, s2))
{
IF_LINT (free (s1));
IF_LINT (free (s2));
exit (EXIT_SUCCESS);
}
free (s1);
free (s2);
/* Upon any failure, let the more general code deal with it.
*/
}
if (format_str == NULL)
format_str = get_default_format (first, step, last);
print_numbers (format_str, layout, first.value, step.value,
last.value);
exit (EXIT_SUCCESS);
}
Specification of the sequ commandCopyright © 2013 Bart Masse.docx

More Related Content

Similar to Specification of the sequ commandCopyright © 2013 Bart Masse.docx

OverviewIn this assignment you will write your own shell i.docx
OverviewIn this assignment you will write your own shell i.docxOverviewIn this assignment you will write your own shell i.docx
OverviewIn this assignment you will write your own shell i.docx
alfred4lewis58146
 
#include string.h#include stdlib.h#include systypes.h.docx
#include string.h#include stdlib.h#include systypes.h.docx#include string.h#include stdlib.h#include systypes.h.docx
#include string.h#include stdlib.h#include systypes.h.docx
AASTHA76
 
Compiler Design and Construction COSC 5353Project Instructions -
Compiler Design and Construction COSC 5353Project Instructions -Compiler Design and Construction COSC 5353Project Instructions -
Compiler Design and Construction COSC 5353Project Instructions -
LynellBull52
 
12 computer science_notes_ch01_overview_of_cpp
12 computer science_notes_ch01_overview_of_cpp12 computer science_notes_ch01_overview_of_cpp
12 computer science_notes_ch01_overview_of_cpp
sharvivek
 

Similar to Specification of the sequ commandCopyright © 2013 Bart Masse.docx (20)

Sdl Basic
Sdl BasicSdl Basic
Sdl Basic
 
lec4.docx
lec4.docxlec4.docx
lec4.docx
 
OverviewIn this assignment you will write your own shell i.docx
OverviewIn this assignment you will write your own shell i.docxOverviewIn this assignment you will write your own shell i.docx
OverviewIn this assignment you will write your own shell i.docx
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
C notes.pdf
C notes.pdfC notes.pdf
C notes.pdf
 
functions modules and exceptions handlings.ppt
functions modules and exceptions handlings.pptfunctions modules and exceptions handlings.ppt
functions modules and exceptions handlings.ppt
 
Complete c programming presentation
Complete c programming presentationComplete c programming presentation
Complete c programming presentation
 
Control structures pyhton
Control structures  pyhtonControl structures  pyhton
Control structures pyhton
 
Input and output basic of c++ programming and escape sequences
Input and output basic of c++ programming and escape sequencesInput and output basic of c++ programming and escape sequences
Input and output basic of c++ programming and escape sequences
 
Go1
Go1Go1
Go1
 
424769021-1-First-C-Program-1-ppt (1).ppt
424769021-1-First-C-Program-1-ppt (1).ppt424769021-1-First-C-Program-1-ppt (1).ppt
424769021-1-First-C-Program-1-ppt (1).ppt
 
fds unit1.docx
fds unit1.docxfds unit1.docx
fds unit1.docx
 
Chapter 2: Introduction to Bash Scripting
Chapter 2: Introduction to Bash ScriptingChapter 2: Introduction to Bash Scripting
Chapter 2: Introduction to Bash Scripting
 
Introduction to c
Introduction to cIntroduction to c
Introduction to c
 
#include string.h#include stdlib.h#include systypes.h.docx
#include string.h#include stdlib.h#include systypes.h.docx#include string.h#include stdlib.h#include systypes.h.docx
#include string.h#include stdlib.h#include systypes.h.docx
 
Compiler Design and Construction COSC 5353Project Instructions -
Compiler Design and Construction COSC 5353Project Instructions -Compiler Design and Construction COSC 5353Project Instructions -
Compiler Design and Construction COSC 5353Project Instructions -
 
12 computer science_notes_ch01_overview_of_cpp
12 computer science_notes_ch01_overview_of_cpp12 computer science_notes_ch01_overview_of_cpp
12 computer science_notes_ch01_overview_of_cpp
 
88 c-programs
88 c-programs88 c-programs
88 c-programs
 
88 c programs 15184
88 c programs 1518488 c programs 15184
88 c programs 15184
 
Variants Density along DNA Sequence
Variants Density along DNA SequenceVariants Density along DNA Sequence
Variants Density along DNA Sequence
 

More from rafbolet0

Summarize the key ideas of each of these texts and explain how they .docx
Summarize the key ideas of each of these texts and explain how they .docxSummarize the key ideas of each of these texts and explain how they .docx
Summarize the key ideas of each of these texts and explain how they .docx
rafbolet0
 
Submit the rough draft of your geology project. Included in your rou.docx
Submit the rough draft of your geology project. Included in your rou.docxSubmit the rough draft of your geology project. Included in your rou.docx
Submit the rough draft of your geology project. Included in your rou.docx
rafbolet0
 
Submit your paper of Sections III and IV of the final project. Spe.docx
Submit your paper of Sections III and IV of the final project. Spe.docxSubmit your paper of Sections III and IV of the final project. Spe.docx
Submit your paper of Sections III and IV of the final project. Spe.docx
rafbolet0
 
Submit the finished product for your Geology Project. Please include.docx
Submit the finished product for your Geology Project. Please include.docxSubmit the finished product for your Geology Project. Please include.docx
Submit the finished product for your Geology Project. Please include.docx
rafbolet0
 
Submit Files - Assignment 1 Role of Manager and Impact of Organizati.docx
Submit Files - Assignment 1 Role of Manager and Impact of Organizati.docxSubmit Files - Assignment 1 Role of Manager and Impact of Organizati.docx
Submit Files - Assignment 1 Role of Manager and Impact of Organizati.docx
rafbolet0
 
SSChaSimple RegressionSimple Regressionpter C.docx
SSChaSimple RegressionSimple Regressionpter  C.docxSSChaSimple RegressionSimple Regressionpter  C.docx
SSChaSimple RegressionSimple Regressionpter C.docx
rafbolet0
 
SRF Journal EntriesreferenceAccount TitlesDebitsCredits3-CType jou.docx
SRF Journal EntriesreferenceAccount TitlesDebitsCredits3-CType jou.docxSRF Journal EntriesreferenceAccount TitlesDebitsCredits3-CType jou.docx
SRF Journal EntriesreferenceAccount TitlesDebitsCredits3-CType jou.docx
rafbolet0
 
srcCommissionCalculation.javasrcCommissionCalculation.javaimpo.docx
srcCommissionCalculation.javasrcCommissionCalculation.javaimpo.docxsrcCommissionCalculation.javasrcCommissionCalculation.javaimpo.docx
srcCommissionCalculation.javasrcCommissionCalculation.javaimpo.docx
rafbolet0
 
SPSS Assignment Data.savWeek 6, Using Marketing Channel.docx
SPSS Assignment Data.savWeek 6, Using Marketing Channel.docxSPSS Assignment Data.savWeek 6, Using Marketing Channel.docx
SPSS Assignment Data.savWeek 6, Using Marketing Channel.docx
rafbolet0
 
SQLServerFilesCars.mdf__MACOSXSQLServerFiles._Cars.mdf.docx
SQLServerFilesCars.mdf__MACOSXSQLServerFiles._Cars.mdf.docxSQLServerFilesCars.mdf__MACOSXSQLServerFiles._Cars.mdf.docx
SQLServerFilesCars.mdf__MACOSXSQLServerFiles._Cars.mdf.docx
rafbolet0
 
Square, Inc. is a financial services, merchant services aggregat.docx
Square, Inc. is a financial services, merchant services aggregat.docxSquare, Inc. is a financial services, merchant services aggregat.docx
Square, Inc. is a financial services, merchant services aggregat.docx
rafbolet0
 
SQL SQL 2) Add 25 CUSTOMERSs so that you now have 50 total..docx
SQL SQL 2) Add 25 CUSTOMERSs so that you now have 50 total..docxSQL SQL 2) Add 25 CUSTOMERSs so that you now have 50 total..docx
SQL SQL 2) Add 25 CUSTOMERSs so that you now have 50 total..docx
rafbolet0
 
SPSS InputStephanie Crookston, Dominique.docx
SPSS InputStephanie Crookston, Dominique.docxSPSS InputStephanie Crookston, Dominique.docx
SPSS InputStephanie Crookston, Dominique.docx
rafbolet0
 
Spring  2015  –  MAT  137  –Luedeker       Na.docx
Spring  2015  –  MAT  137  –Luedeker        Na.docxSpring  2015  –  MAT  137  –Luedeker        Na.docx
Spring  2015  –  MAT  137  –Luedeker       Na.docx
rafbolet0
 
Springdale Shopping SurveyThe major shopping areas in the com.docx
Springdale Shopping SurveyThe major shopping areas in the com.docxSpringdale Shopping SurveyThe major shopping areas in the com.docx
Springdale Shopping SurveyThe major shopping areas in the com.docx
rafbolet0
 
Springfield assignment InstructionFrom the given information, yo.docx
Springfield assignment InstructionFrom the given information, yo.docxSpringfield assignment InstructionFrom the given information, yo.docx
Springfield assignment InstructionFrom the given information, yo.docx
rafbolet0
 

More from rafbolet0 (20)

Summarize the key ideas of each of these texts and explain how they .docx
Summarize the key ideas of each of these texts and explain how they .docxSummarize the key ideas of each of these texts and explain how they .docx
Summarize the key ideas of each of these texts and explain how they .docx
 
Submit, individually, different kinds of data breaches, the threats .docx
Submit, individually, different kinds of data breaches, the threats .docxSubmit, individually, different kinds of data breaches, the threats .docx
Submit, individually, different kinds of data breaches, the threats .docx
 
Submit your personal crimes analysis using Microsoft® PowerPoi.docx
Submit your personal crimes analysis using Microsoft® PowerPoi.docxSubmit your personal crimes analysis using Microsoft® PowerPoi.docx
Submit your personal crimes analysis using Microsoft® PowerPoi.docx
 
Submit two pages (double spaced, 12 point font) describing a musical.docx
Submit two pages (double spaced, 12 point font) describing a musical.docxSubmit two pages (double spaced, 12 point font) describing a musical.docx
Submit two pages (double spaced, 12 point font) describing a musical.docx
 
Submit the rough draft of your geology project. Included in your rou.docx
Submit the rough draft of your geology project. Included in your rou.docxSubmit the rough draft of your geology project. Included in your rou.docx
Submit the rough draft of your geology project. Included in your rou.docx
 
Submit your paper of Sections III and IV of the final project. Spe.docx
Submit your paper of Sections III and IV of the final project. Spe.docxSubmit your paper of Sections III and IV of the final project. Spe.docx
Submit your paper of Sections III and IV of the final project. Spe.docx
 
Submit the finished product for your Geology Project. Please include.docx
Submit the finished product for your Geology Project. Please include.docxSubmit the finished product for your Geology Project. Please include.docx
Submit the finished product for your Geology Project. Please include.docx
 
Submit the Background Information portion of the final project, desc.docx
Submit the Background Information portion of the final project, desc.docxSubmit the Background Information portion of the final project, desc.docx
Submit the Background Information portion of the final project, desc.docx
 
Submit Files - Assignment 1 Role of Manager and Impact of Organizati.docx
Submit Files - Assignment 1 Role of Manager and Impact of Organizati.docxSubmit Files - Assignment 1 Role of Manager and Impact of Organizati.docx
Submit Files - Assignment 1 Role of Manager and Impact of Organizati.docx
 
SSChaSimple RegressionSimple Regressionpter C.docx
SSChaSimple RegressionSimple Regressionpter  C.docxSSChaSimple RegressionSimple Regressionpter  C.docx
SSChaSimple RegressionSimple Regressionpter C.docx
 
SRF Journal EntriesreferenceAccount TitlesDebitsCredits3-CType jou.docx
SRF Journal EntriesreferenceAccount TitlesDebitsCredits3-CType jou.docxSRF Journal EntriesreferenceAccount TitlesDebitsCredits3-CType jou.docx
SRF Journal EntriesreferenceAccount TitlesDebitsCredits3-CType jou.docx
 
srcCommissionCalculation.javasrcCommissionCalculation.javaimpo.docx
srcCommissionCalculation.javasrcCommissionCalculation.javaimpo.docxsrcCommissionCalculation.javasrcCommissionCalculation.javaimpo.docx
srcCommissionCalculation.javasrcCommissionCalculation.javaimpo.docx
 
SPSS Assignment Data.savWeek 6, Using Marketing Channel.docx
SPSS Assignment Data.savWeek 6, Using Marketing Channel.docxSPSS Assignment Data.savWeek 6, Using Marketing Channel.docx
SPSS Assignment Data.savWeek 6, Using Marketing Channel.docx
 
SQLServerFilesCars.mdf__MACOSXSQLServerFiles._Cars.mdf.docx
SQLServerFilesCars.mdf__MACOSXSQLServerFiles._Cars.mdf.docxSQLServerFilesCars.mdf__MACOSXSQLServerFiles._Cars.mdf.docx
SQLServerFilesCars.mdf__MACOSXSQLServerFiles._Cars.mdf.docx
 
Square, Inc. is a financial services, merchant services aggregat.docx
Square, Inc. is a financial services, merchant services aggregat.docxSquare, Inc. is a financial services, merchant services aggregat.docx
Square, Inc. is a financial services, merchant services aggregat.docx
 
SQL SQL 2) Add 25 CUSTOMERSs so that you now have 50 total..docx
SQL SQL 2) Add 25 CUSTOMERSs so that you now have 50 total..docxSQL SQL 2) Add 25 CUSTOMERSs so that you now have 50 total..docx
SQL SQL 2) Add 25 CUSTOMERSs so that you now have 50 total..docx
 
SPSS InputStephanie Crookston, Dominique.docx
SPSS InputStephanie Crookston, Dominique.docxSPSS InputStephanie Crookston, Dominique.docx
SPSS InputStephanie Crookston, Dominique.docx
 
Spring  2015  –  MAT  137  –Luedeker       Na.docx
Spring  2015  –  MAT  137  –Luedeker        Na.docxSpring  2015  –  MAT  137  –Luedeker        Na.docx
Spring  2015  –  MAT  137  –Luedeker       Na.docx
 
Springdale Shopping SurveyThe major shopping areas in the com.docx
Springdale Shopping SurveyThe major shopping areas in the com.docxSpringdale Shopping SurveyThe major shopping areas in the com.docx
Springdale Shopping SurveyThe major shopping areas in the com.docx
 
Springfield assignment InstructionFrom the given information, yo.docx
Springfield assignment InstructionFrom the given information, yo.docxSpringfield assignment InstructionFrom the given information, yo.docx
Springfield assignment InstructionFrom the given information, yo.docx
 

Recently uploaded

Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
ZurliaSoop
 
The basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptxThe basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptx
heathfieldcps1
 

Recently uploaded (20)

21st_Century_Skills_Framework_Final_Presentation_2.pptx
21st_Century_Skills_Framework_Final_Presentation_2.pptx21st_Century_Skills_Framework_Final_Presentation_2.pptx
21st_Century_Skills_Framework_Final_Presentation_2.pptx
 
ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.
 
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptxHMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
HMCS Max Bernays Pre-Deployment Brief (May 2024).pptx
 
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptxOn_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
 
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
 
Food safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdfFood safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdf
 
COMMUNICATING NEGATIVE NEWS - APPROACHES .pptx
COMMUNICATING NEGATIVE NEWS - APPROACHES .pptxCOMMUNICATING NEGATIVE NEWS - APPROACHES .pptx
COMMUNICATING NEGATIVE NEWS - APPROACHES .pptx
 
latest AZ-104 Exam Questions and Answers
latest AZ-104 Exam Questions and Answerslatest AZ-104 Exam Questions and Answers
latest AZ-104 Exam Questions and Answers
 
How to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxHow to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptx
 
General Principles of Intellectual Property: Concepts of Intellectual Proper...
General Principles of Intellectual Property: Concepts of Intellectual  Proper...General Principles of Intellectual Property: Concepts of Intellectual  Proper...
General Principles of Intellectual Property: Concepts of Intellectual Proper...
 
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
 
Exploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptx
Exploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptxExploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptx
Exploring_the_Narrative_Style_of_Amitav_Ghoshs_Gun_Island.pptx
 
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptxBasic Civil Engineering first year Notes- Chapter 4 Building.pptx
Basic Civil Engineering first year Notes- Chapter 4 Building.pptx
 
Graduate Outcomes Presentation Slides - English
Graduate Outcomes Presentation Slides - EnglishGraduate Outcomes Presentation Slides - English
Graduate Outcomes Presentation Slides - English
 
Kodo Millet PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...
Kodo Millet  PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...Kodo Millet  PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...
Kodo Millet PPT made by Ghanshyam bairwa college of Agriculture kumher bhara...
 
Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)
 
FSB Advising Checklist - Orientation 2024
FSB Advising Checklist - Orientation 2024FSB Advising Checklist - Orientation 2024
FSB Advising Checklist - Orientation 2024
 
Plant propagation: Sexual and Asexual propapagation.pptx
Plant propagation: Sexual and Asexual propapagation.pptxPlant propagation: Sexual and Asexual propapagation.pptx
Plant propagation: Sexual and Asexual propapagation.pptx
 
The basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptxThe basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptx
 
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
 

Specification of the sequ commandCopyright © 2013 Bart Masse.docx

  • 1. Specification of the "sequ" command Copyright © 2013 Bart Massey Revision 0: 1 October 2013 This specification describes the "universal sequence" command sequ. The sequ command is a backward-compatible set of extensions to the UNIX [seq](http://www.gnu.org/software/coreutils/manual/html_node/ seq-invocation.html) command. There are many implementations of seq out there: this specification is built on the seq supplied with GNU Coreutils version 8.21. The seq command emits a monotonically increasing sequence of numbers. It is most commonly used in shell scripting: TOTAL=0 for i in `seq 1 10` do TOTAL=`expr $i + $TOTAL` done echo $TOTAL prints 55 on standard output. The full sequ command does this basic counting operation, plus much more. This specification of sequ is in several stages, known as compliance levels. Each compliance level adds required functionality to the sequ specification. Level 1 compliance is equivalent to the Coreutils seq command. The usual specification language applies to this document: MAY, SHOULD, MUST (and their negations) are used in the standard fashion.
  • 2. Wherever the specification indicates an error, a conforming sequ implementation MUST immediately issue appropriate error message specific to the problem. The implementation then MUST exit, with a status indicating failure to the invoking process or system. On UNIX systems, the error MUST be indicated by exiting with status code 1. When a conforming sequ implementation successfully completes its output, it MUST immediately exit, with a status indicating success to the invoking process or systems. On UNIX systems, success MUST be indicated by exiting with status code 0. Compliance Level 0 Compliance Level 0 of sequ requires absolute minimum functionality. A CL0 sequ MUST accept exactly two command- line arguments. Each argument SHOULD be a representation of an integer value. Any other supplied argument syntax is an error. If the first integer argument is numerically greater than the second, the sequ command MUST emit no output. Otherwise, sequ MUST print on its output each of the integers between the first and second argument, inclusive. Each output integer MUST be on a line by itself, that is, a line terminated with an appropriate line terminator for the host environment. Compliance Level 1 Compliance Level 1 of sequ adds the full functionality of GNU Coreutils seq. This includes the "--format", "--separator", "-- equal-width", "--help" and "--version" arguments (as well as the one-character abbreviations of these), the increment argument, and support for floating-point numbers. The sequ initialization and increment arguments are now optional, as per the seq spec.
  • 3. The sequ "--format" specifier MAY format floating-point numbers differently than seq, but it MUST follow some well- described and reasonable floating-point formatting standard. Backslash-escapes in the "-s" argument string MUST be processed as in C printf(3). Start a text file of notes on what you're about to do. As you work on this assignment, make notes about you findings and progress. You will turn in your notes at the end. Read CL1 of the sequ spec. Note down any questions and concerns you have about it. Write tests for CL1 of sequ. Be sure to have enough tests to catch problems with your implementation. Write pseudocode for any parts of CL1 of sequ that you think need it. Check your pseudocode into the repo. Write CL1 of sequ. Verify that it passes your tests. Record test results and debugging steps in your notes. Compliance Level 2 Compliance Level 2 of sequ adds additional convenience arguments for formatting. The arguments that MUST be accepted are as follows: -W, --words: Output the sequence as a single space-separated line. Equivalent to "-s ' '". -p, --pad : Output the sequence with elements padded on the left to be all of equal width: the pad character is given by the
  • 4. single-char pad string . Backslash-escapes in MUST be processed as in C printf(3). Note that the "-w" command of level 2 is equivalent to "-p '0'". -P, --pad-spaces: Output the sequence with elements padded with spaces on the left to be all of equal width. Equivalent to "- p ' '". Compliance Level 3 Compliance Level 3 of sequ adds the ability to have sequences of types other than floating-point numbers. Specifically, CL3 sequ MUST accept as arguments and output as results: arbitrary-precision integers, single lowercase alphabetic (ASCII) letters, single uppercase alphabetic (ASCII) letters, and lowercase or uppercase unsigned Roman Numerals. The sequ command MUST accept a new flag, "--format-word" or "-F", that takes a one-word argument indicating the type of the sequence. The sequ command MUST accept the format-word arguments "arabic" (for integers), "floating", "alpha" (for letters), "ALPHA", "roman" or "ROMAN"; the all-uppercase variants indicate uppercase sequences. The sequ command MUST accept limit arguments (start, end, and increment) in the format consistent with the format-word. Arabic limit arguments MAY be "promoted" to Roman Numerals when Roman output is requested. The increment argument for alpha formats MUST be arabic. Otherwise, the limit arguments MUST be in the same format as the format- word. When no format-word is given, the format MUST be inferred from the format of the mandatory end argument. Compliance Level 4
  • 5. Compliance Level 4 of sequ adds the ability to number the lines of a textfile presented on the input. CL4 sequ MUST accept the "--number-lines" / "-n" argument. This argument indicates that, rather than outputting the sequence on standard output, sequ will act as a filter, numbering lines of a file read from standard input to standard output. Each line "number" will be in the format specified by the "--format- word" argument, or inferred from the start or increment limit argument if the "--format-word" argument is not supplied. The end argument is irrelevant when "--number-lines" is supplied; it MUST NOT be accepted. The separator between the line number and the line may be given by the "--separator" argument, defaulting to space. Compliance Level 5 Compliance Level 5 of sequ adds the ability to infer a sequence from a given prefix. As an alternative to the limit arguments of previous Compliance Levels, CL5 sequ may accept a sequence specifier of the form: value [value] [value] ... ".." value When the ".." argument is present, the non-flag arguments MUST be parsed in inference mode. In inference mode, sequ picks a best match for the pattern (partial sequence of values leading up to the ".."), and then continues the sequence until the end value (after the "..") is succeeded. /* seq - print sequence of numbers to standard output.
  • 6. Copyright (C) 1994-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* Written by Ulrich Drepper. */ #include <config.h> #include <getopt.h> #include <stdio.h> #include <sys/types.h> #include "system.h" #include "c-strtod.h" #include "error.h" #include "quote.h" #include "xstrtod.h" /* Roll our own isfinite rather than using <math.h>, so that we
  • 7. don't have to worry about linking -lm just for isfinite. */ #ifndef isfinite # define isfinite(x) ((x) * 0 == 0) #endif /* The official name of this program (e.g., no 'g' prefix). */ #define PROGRAM_NAME "seq" #define AUTHORS proper_name ("Ulrich Drepper") /* If true print all number with equal width. */ static bool equal_width; /* The string used to separate two numbers. */ static char const *separator; /* The string output after all numbers have been output. Usually "n" or "0". */ static char const terminator[] = "n"; static struct option const long_options[] = { { "equal-width", no_argument, NULL, 'w'}, { "format", required_argument, NULL, 'f'}, { "separator", required_argument, NULL, 's'}, {GETOPT_HELP_OPTION_DECL}, {GETOPT_VERSION_OPTION_DECL}, { NULL, 0, NULL, 0} }; void usage (int status) { if (status != EXIT_SUCCESS) emit_try_help ();
  • 8. else { printf (_(" Usage: %s [OPTION]... LASTn or: %s [OPTION]... FIRST LASTn or: %s [OPTION]... FIRST INCREMENT LASTn "), program_name, program_name, program_name); fputs (_(" Print numbers from FIRST to LAST, in steps of INCREMENT.n "), stdout); emit_mandatory_arg_note (); fputs (_(" -f, --format=FORMAT use printf style floating-point FORMATn -s, --separator=STRING use STRING to separate numbers (default: n)n -w, --equal-width equalize width by padding with leading zeroesn "), stdout); fputs (HELP_OPTION_DESCRIPTION, stdout); fputs (VERSION_OPTION_DESCRIPTION, stdout); fputs (_(" n If FIRST or INCREMENT is omitted, it defaults to 1. That is, ann omitted INCREMENT defaults to 1 even when LAST is smaller than FIRST.n The sequence of numbers ends when the sum of the current number andn INCREMENT would become greater than LAST.n FIRST, INCREMENT, and LAST are interpreted as floating point values.n INCREMENT is usually positive if FIRST is smaller than
  • 9. LAST, andn INCREMENT is usually negative if FIRST is greater than LAST.n "), stdout); fputs (_(" FORMAT must be suitable for printing one argument of type 'double';n it defaults to %.PRECf if FIRST, INCREMENT, and LAST are all fixed pointn decimal numbers with maximum precision PREC, and to %g otherwise.n "), stdout); emit_ancillary_info (); } exit (status); } /* A command-line operand. */ struct operand { /* Its value, converted to 'long double'. */ long double value; /* Its print width, if it were printed out in a form similar to its input form. An input like "-.1" is treated like "-0.1", and an input like "1." is treated like "1", but otherwise widths are left alone. */ size_t width; /* Number of digits after the decimal point, or INT_MAX if the number can't easily be expressed as a fixed-point number. */ int precision; }; typedef struct operand operand;
  • 10. /* Description of what a number-generating format will generate. */ struct layout { /* Number of bytes before and after the number. */ size_t prefix_len; size_t suffix_len; }; /* Read a long double value from the command line. Return if the string is correct else signal error. */ static operand scan_arg (const char *arg) { operand ret; if (! xstrtold (arg, NULL, &ret.value, c_strtold)) { error (0, 0, _("invalid floating point argument: %s"), arg); usage (EXIT_FAILURE); } /* We don't output spaces or '+' so don't include in width */ while (isspace (to_uchar (*arg)) || *arg == '+') arg++; ret.width = strlen (arg); ret.precision = INT_MAX; if (! arg[strcspn (arg, "xX")] && isfinite (ret.value)) { char const *decimal_point = strchr (arg, '.'); if (! decimal_point) ret.precision = 0; else
  • 11. { size_t fraction_len = strcspn (decimal_point + 1, "eE"); if (fraction_len <= INT_MAX) ret.precision = fraction_len; ret.width += (fraction_len == 0 /* #. -> # */ ? -1 : (decimal_point == arg /* .# -> 0.# */ || ! ISDIGIT (decimal_point[-1]))); /* -.# -> 0.# */ } char const *e = strchr (arg, 'e'); if (! e) e = strchr (arg, 'E'); if (e) { long exponent = strtol (e + 1, NULL, 10); ret.precision += exponent < 0 ? -exponent : 0; /* Don't account for e.... in the width since this is not output. */ ret.width -= strlen (arg) - (e - arg); /* Adjust the width as per the exponent. */ if (exponent < 0) { if (decimal_point) { if (e == decimal_point + 1) /* undo #. -> # above */ ret.width++; } else ret.width++; exponent = -exponent; } ret.width += exponent;
  • 12. } } return ret; } /* If FORMAT is a valid printf format for a double argument, return its long double equivalent, allocated from dynamic storage, and store into *LAYOUT a description of the output layout; otherwise, report an error and exit. */ static char const * long_double_format (char const *fmt, struct layout *layout) { size_t i; size_t prefix_len = 0; size_t suffix_len = 0; size_t length_modifier_offset; bool has_L; for (i = 0; ! (fmt[i] == '%' && fmt[i + 1] != '%'); i += (fmt[i] == '%') + 1) { if (!fmt[i]) error (EXIT_FAILURE, 0, _("format %s has no %% directive"), quote (fmt)); prefix_len++; } i++; i += strspn (fmt + i, "-+#0 '"); i += strspn (fmt + i, "0123456789"); if (fmt[i] == '.')
  • 13. { i++; i += strspn (fmt + i, "0123456789"); } length_modifier_offset = i; has_L = (fmt[i] == 'L'); i += has_L; if (fmt[i] == '0') error (EXIT_FAILURE, 0, _("format %s ends in %%"), quote (fmt)); if (! strchr ("efgaEFGA", fmt[i])) error (EXIT_FAILURE, 0, _("format %s has unknown %%%c directive"), quote (fmt), fmt[i]); for (i++; ; i += (fmt[i] == '%') + 1) if (fmt[i] == '%' && fmt[i + 1] != '%') error (EXIT_FAILURE, 0, _("format %s has too many %% directives"), quote (fmt)); else if (fmt[i]) suffix_len++; else { size_t format_size = i + 1; char *ldfmt = xmalloc (format_size + 1); memcpy (ldfmt, fmt, length_modifier_offset); ldfmt[length_modifier_offset] = 'L'; strcpy (ldfmt + length_modifier_offset + 1, fmt + length_modifier_offset + has_L); layout->prefix_len = prefix_len; layout->suffix_len = suffix_len; return ldfmt; } }
  • 14. /* Actually print the sequence of numbers in the specified range, with the given or default stepping and format. */ static void print_numbers (char const *fmt, struct layout layout, long double first, long double step, long double last) { bool out_of_range = (step < 0 ? first < last : last < first); if (! out_of_range) { long double x = first; long double i; for (i = 1; ; i++) { long double x0 = x; printf (fmt, x); if (out_of_range) break; x = first + i * step; out_of_range = (step < 0 ? x < last : last < x); if (out_of_range) { /* If the number just past LAST prints as a value equal to LAST, and prints differently from the previous number, then print the number. This avoids problems with rounding. For example, with the x86 it causes "seq 0 0.000001 0.000003" to print 0.000003 instead of stopping at 0.000002. */ bool print_extra_number = false;
  • 15. long double x_val; char *x_str; int x_strlen; setlocale (LC_NUMERIC, "C"); x_strlen = asprintf (&x_str, fmt, x); setlocale (LC_NUMERIC, ""); if (x_strlen < 0) xalloc_die (); x_str[x_strlen - layout.suffix_len] = '0'; if (xstrtold (x_str + layout.prefix_len, NULL, &x_val, c_strtold) && x_val == last) { char *x0_str = NULL; if (asprintf (&x0_str, fmt, x0) < 0) xalloc_die (); print_extra_number = !STREQ (x0_str, x_str); free (x0_str); } free (x_str); if (! print_extra_number) break; } fputs (separator, stdout); } fputs (terminator, stdout); } } /* Return the default format given FIRST, STEP, and LAST. */ static char const * get_default_format (operand first, operand step, operand last)
  • 16. { static char format_buf[sizeof "%0.Lf" + 2 * INT_STRLEN_BOUND (int)]; int prec = MAX (first.precision, step.precision); if (prec != INT_MAX && last.precision != INT_MAX) { if (equal_width) { /* increase first_width by any increased precision in step */ size_t first_width = first.width + (prec - first.precision); /* adjust last_width to use precision from first/step */ size_t last_width = last.width + (prec - last.precision); if (last.precision && prec == 0) last_width--; /* don't include space for '.' */ if (last.precision == 0 && prec) last_width++; /* include space for '.' */ if (first.precision == 0 && prec) first_width++; /* include space for '.' */ size_t width = MAX (first_width, last_width); if (width <= INT_MAX) { int w = width; sprintf (format_buf, "%%0%d.%dLf", w, prec); return format_buf; } } else { sprintf (format_buf, "%%.%dLf", prec); return format_buf; } }
  • 17. return "%Lg"; } /* The NUL-terminated string S0 of length S_LEN represents a valid non-negative decimal integer. Adjust the string and length so that the pair describe the next-larger value. */ static void incr (char **s0, size_t *s_len) { char *s = *s0; char *endp = s + *s_len - 1; do { if ((*endp)++ < '9') return; *endp-- = '0'; } while (endp >= s); *--(*s0) = '1'; ++*s_len; } /* Compare A and B (each a NUL-terminated digit string), with lengths given by A_LEN and B_LEN. Return +1 if A < B, -1 if B < A, else 0. */ static int cmp (char const *a, size_t a_len, char const *b, size_t b_len) { if (a_len < b_len) return -1; if (b_len < a_len) return 1; return (strcmp (a, b));
  • 18. } /* Trim leading 0's from S, but if S is all 0's, leave one. Return a pointer to the trimmed string. */ static char const * _GL_ATTRIBUTE_PURE trim_leading_zeros (char const *s) { char const *p = s; while (*s == '0') ++s; /* If there were only 0's, back up, to leave one. */ if (!*s && s != p) --s; return s; } /* Print all whole numbers from A to B, inclusive -- to stdout, each followed by a newline. If B < A, return false and print nothing. Otherwise, return true. */ static bool seq_fast (char const *a, char const *b) { /* Skip past any leading 0's. Without this, our naive cmp function would declare 000 to be larger than 99. */ a = trim_leading_zeros (a); b = trim_leading_zeros (b); size_t p_len = strlen (a); size_t q_len = strlen (b); size_t n = MAX (p_len, q_len); char *p0 = xmalloc (n + 1); char *p = memcpy (p0 + n - p_len, a, p_len + 1); char *q0 = xmalloc (n + 1);
  • 19. char *q = memcpy (q0 + n - q_len, b, q_len + 1); bool ok = cmp (p, p_len, q, q_len) <= 0; if (ok) { /* Buffer at least this many numbers per fwrite call. This gives a speed-up of more than 2x over the unbuffered code when printing the first 10^9 integers. */ enum {N = 40}; char *buf = xmalloc (N * (n + 1)); char const *buf_end = buf + N * (n + 1); char *z = buf; /* Write first number to buffer. */ z = mempcpy (z, p, p_len); /* Append separator then number. */ while (cmp (p, p_len, q, q_len) < 0) { *z++ = *separator; incr (&p, &p_len); z = mempcpy (z, p, p_len); /* If no place for another separator + number then output buffer so far, and reset to start of buffer. */ if (buf_end - (n + 1) < z) { fwrite (buf, z - buf, 1, stdout); z = buf; } } /* Write any remaining buffered output, and the terminator. */ *z++ = *terminator;
  • 20. fwrite (buf, z - buf, 1, stdout); IF_LINT (free (buf)); } free (p0); free (q0); return ok; } /* Return true if S consists of at least one digit and no non- digits. */ static bool _GL_ATTRIBUTE_PURE all_digits_p (char const *s) { size_t n = strlen (s); return ISDIGIT (s[0]) && n == strspn (s, "0123456789"); } int main (int argc, char **argv) { int optc; operand first = { 1, 1, 0 }; operand step = { 1, 1, 0 }; operand last; struct layout layout = { 0, 0 }; /* The printf(3) format used for output. */ char const *format_str = NULL; initialize_main (&argc, &argv); set_program_name (argv[0]); setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE);
  • 21. atexit (close_stdout); equal_width = false; separator = "n"; /* We have to handle negative numbers in the command line but this conflicts with the command line arguments. So explicitly check first whether the next argument looks like a negative number. */ while (optind < argc) { if (argv[optind][0] == '-' && ((optc = argv[optind][1]) == '.' || ISDIGIT (optc))) { /* means negative number */ break; } optc = getopt_long (argc, argv, "+f:s:w", long_options, NULL); if (optc == -1) break; switch (optc) { case 'f': format_str = optarg; break; case 's': separator = optarg; break; case 'w':
  • 22. equal_width = true; break; case_GETOPT_HELP_CHAR; case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); default: usage (EXIT_FAILURE); } } unsigned int n_args = argc - optind; if (n_args < 1) { error (0, 0, _("missing operand")); usage (EXIT_FAILURE); } if (3 < n_args) { error (0, 0, _("extra operand %s"), quote (argv[optind + 3])); usage (EXIT_FAILURE); } if (format_str) format_str = long_double_format (format_str, &layout); if (format_str != NULL && equal_width) { error (0, 0, _("format string may not be specified" " when printing equal width strings")); usage (EXIT_FAILURE); }
  • 23. /* If the following hold: - no format string, [FIXME: relax this, eventually] - integer start (or no start) - integer end - increment == 1 or not specified [FIXME: relax this, eventually] then use the much more efficient integer-only code. */ if (all_digits_p (argv[optind]) && (n_args == 1 || all_digits_p (argv[optind + 1])) && (n_args < 3 || (STREQ ("1", argv[optind + 1]) && all_digits_p (argv[optind + 2]))) && !equal_width && !format_str && strlen (separator) == 1) { char const *s1 = n_args == 1 ? "1" : argv[optind]; char const *s2 = argv[optind + (n_args - 1)]; if (seq_fast (s1, s2)) exit (EXIT_SUCCESS); /* Upon any failure, let the more general code deal with it. */ } last = scan_arg (argv[optind++]); if (optind < argc) { first = last; last = scan_arg (argv[optind++]); if (optind < argc) { step = last; last = scan_arg (argv[optind++]); }
  • 24. } if (first.precision == 0 && step.precision == 0 && last.precision == 0 && 0 <= first.value && step.value == 1 && 0 <= last.value && !equal_width && !format_str && strlen (separator) == 1) { char *s1; char *s2; if (asprintf (&s1, "%0.Lf", first.value) < 0) xalloc_die (); if (asprintf (&s2, "%0.Lf", last.value) < 0) xalloc_die (); if (seq_fast (s1, s2)) { IF_LINT (free (s1)); IF_LINT (free (s2)); exit (EXIT_SUCCESS); } free (s1); free (s2); /* Upon any failure, let the more general code deal with it. */ } if (format_str == NULL) format_str = get_default_format (first, step, last); print_numbers (format_str, layout, first.value, step.value, last.value); exit (EXIT_SUCCESS); }