#include <inttypes.h>
#include <errno.h>
+#include "xstrtol.h"
+
#include "fish.h"
int
static int
parse_size (const char *str, off_t *size_rtn)
{
- uint64_t size;
- char type;
-
- /* Note that the parsing here is looser than what is specified in the
- * help, but we may tighten it up in future so beware.
- */
- if (sscanf (str, "%"SCNu64"%c", &size, &type) == 2) {
- switch (type) {
- case 'k': case 'K': size *= 1024ULL; break;
- case 'm': case 'M': size *= 1024ULL * 1024ULL; break;
- case 'g': case 'G': size *= 1024ULL * 1024ULL * 1024ULL; break;
- case 't': case 'T': size *= 1024ULL * 1024ULL * 1024ULL * 1024ULL; break;
- case 'p': case 'P': size *= 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL; break;
- case 'e': case 'E': size *= 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL; break;
- case 's': size *= 512; break;
- default:
- fprintf (stderr, _("could not parse size specification '%s'\n"), str);
- return -1;
- }
- }
- else if (sscanf (str, "%"SCNu64, &size) == 1)
- size *= 1024ULL;
- else {
- fprintf (stderr, _("could not parse size specification '%s'\n"), str);
+ unsigned long long size;
+ strtol_error xerr;
+
+ xerr = xstrtoull (str, NULL, 0, &size, "0kKMGTPEZY");
+ if (xerr != LONGINT_OK) {
+ fprintf (stderr,
+ _("%s: invalid integer parameter (%s returned %d)\n"),
+ "alloc_disk", "xstrtoull", xerr);
return -1;
}
"\n"
" For more advanced image creation, see qemu-img utility.\n"
"\n"
- " Size can be specified (where <nn> means a number):\n"
- " <nn> number of kilobytes\n"
- " eg: 1440 standard 3.5\" floppy\n"
- " <nn>K or <nn>KB number of kilobytes\n"
- " <nn>M or <nn>MB number of megabytes\n"
- " <nn>G or <nn>GB number of gigabytes\n"
- " <nn>T or <nn>TB number of terabytes\n"
- " <nn>P or <nn>PB number of petabytes\n"
- " <nn>E or <nn>EB number of exabytes\n"
- " <nn>sects number of 512 byte sectors\n"));
+ " Size can be specified using standard suffixes, eg. '1M'.\n"
+ ));
else if (STRCASEEQ (cmd, "echo"))
printf (_("echo - display a line of text\n"
" echo [<params> ...]\n"
"\n"
" For more advanced image creation, see qemu-img utility.\n"
"\n"
- " Size can be specified (where <nn> means a number):\n"
- " <nn> number of kilobytes\n"
- " eg: 1440 standard 3.5\" floppy\n"
- " <nn>K or <nn>KB number of kilobytes\n"
- " <nn>M or <nn>MB number of megabytes\n"
- " <nn>G or <nn>GB number of gigabytes\n"
- " <nn>T or <nn>TB number of terabytes\n"
- " <nn>P or <nn>PB number of petabytes\n"
- " <nn>E or <nn>EB number of exabytes\n"
- " <nn>sects number of 512 byte sectors\n"));
+ " Size can be specified using standard suffixes, eg. '1M'.\n"
+ ));
else if (STRCASEEQ (cmd, "time"))
printf (_("time - measure time taken to run command\n"
" time <command> [<args> ...]\n"
=head1 NUMBERS
-Commands which take integers as parameters use the C convention which
-is to use C<0> to prefix an octal number or C<0x> to prefix a
-hexadecimal number. For example:
+This section applies to all commands which can take integers
+as parameters.
+
+=head2 SIZE SUFFIX
+
+When the command takes a parameter measured in bytes, you can use one
+of the following suffixes to specify kilobytes, megabytes and larger
+sizes:
+
+=over 4
+
+=item B<k> or B<K> or B<KiB>
+
+The size in kilobytes (multiplied by 1024).
+
+=item B<KB>
+
+The size in SI 1000 byte units.
+
+=item B<M> or B<MiB>
+
+The size in megabytes (multiplied by 1048576).
+
+=item B<MB>
+
+The size in SI 1000000 byte units.
+
+=item B<G> or B<GiB>
+
+The size in gigabytes (multiplied by 2**30).
+
+=item B<GB>
+
+The size in SI 10**9 byte units.
+
+=item B<T> or B<TiB>
+
+The size in terabytes (multiplied by 2**40).
+
+=item B<TB>
+
+The size in SI 10**12 byte units.
+
+=item B<P> or B<PiB>
+
+The size in petabytes (multiplied by 2**50).
+
+=item B<PB>
+
+The size in SI 10**15 byte units.
+
+=item B<E> or B<EiB>
+
+The size in exabytes (multiplied by 2**60).
+
+=item B<EB>
+
+The size in SI 10**18 byte units.
+
+=item B<Z> or B<ZiB>
+
+The size in zettabytes (multiplied by 2**70).
+
+=item B<ZB>
+
+The size in SI 10**21 byte units.
+
+=item B<Y> or B<YiB>
+
+The size in yottabytes (multiplied by 2**80).
+
+=item B<YB>
+
+The size in SI 10**24 byte units.
+
+=back
+
+For example:
+
+ truncate-size /file 1G
+
+would truncate the file to 1 gigabyte.
+
+Be careful because a few commands take sizes in kilobytes or megabytes
+(eg. the parameter to L</memsize> is specified in megabytes already).
+Adding a suffix will probably not do what you expect.
+
+=head2 OCTAL AND HEXADECIMAL NUMBERS
+
+For specifying the radix (base) use the C convention: C<0> to prefix
+an octal number or C<0x> to prefix a hexadecimal number. For example:
1234 decimal number 1234
02322 octal number, equivalent to decimal 1234
For more advanced image creation, see L<qemu-img(1)> utility.
-Size can be specified (where C<nn> means a number):
-
-=over 4
-
-=item C<nn> or C<nn>K or C<nn>KB
-
-number of kilobytes, eg: C<1440> = standard 3.5in floppy
-
-=item C<nn>M or C<nn>MB
-
-number of megabytes
-
-=item C<nn>G or C<nn>GB
-
-number of gigabytes
-
-=item C<nn>T or C<nn>TB
-
-number of terabytes
-
-=item C<nn>P or C<nn>PB
-
-number of petabytes
-
-=item C<nn>E or C<nn>EB
-
-number of exabytes
-
-=item C<nn>sects
-
-number of 512 byte sectors
-
-=back
+Size can be specified using standard suffixes, eg. C<1M>.
=head2 echo
For more advanced image creation, see L<qemu-img(1)> utility.
-Size can be specified (where C<nn> means a number):
-
-=over 4
-
-=item C<nn> or C<nn>K or C<nn>KB
-
-number of kilobytes, eg: C<1440> = standard 3.5in floppy
-
-=item C<nn>M or C<nn>MB
-
-number of megabytes
-
-=item C<nn>G or C<nn>GB
-
-number of gigabytes
-
-=item C<nn>T or C<nn>TB
-
-number of terabytes
-
-=item C<nn>P or C<nn>PB
-
-number of petabytes
-
-=item C<nn>E or C<nn>EB
-
-number of exabytes
-
-=item C<nn>sects
-
-number of 512 byte sectors
-
-=back
+Size can be specified using standard suffixes, eg. C<1M>.
=head2 time
set-memsize: memsize: invalid integer parameter (xstrtoll returned 4)
set-memsize: memsize: invalid integer parameter (xstrtoll returned 2)
set-memsize: memsize: invalid integer parameter (xstrtoll returned 2)
-set-memsize: memsize: invalid integer parameter (xstrtoll returned 2)
libguestfs: error: truncate_size: ftruncate: /test: File too large
truncate-size: size: invalid integer parameter (xstrtoll returned 1)
truncate-size: size: invalid integer parameter (xstrtoll returned 4)
truncate-size: size: invalid integer parameter (xstrtoll returned 2)
truncate-size: size: invalid integer parameter (xstrtoll returned 2)
-truncate-size: size: invalid integer parameter (xstrtoll returned 2)
-set-memsize 07777770000000000000
-set-memsize ABC
-set-memsize 09
--set-memsize 123K
-set-memsize 123L
EOF
# these should all provoke parse errors:
-truncate-size /test ABC
-truncate-size /test 09
--truncate-size /test 123K
-truncate-size /test 123L
EOF
grep -Ev 'proc 200' > test.err
rm test.err~
-diff -u test.out rhbz557655-expected.stdout
-diff -u test.err rhbz557655-expected.stderr
+diff -u rhbz557655-expected.stdout test.out
+diff -u rhbz557655-expected.stderr test.err
rm test.out test.err test1.img
pr "#include \"xstrtol.h\"\n";
pr "#include \"fish.h\"\n";
pr "\n";
+ pr "/* Valid suffixes allowed for numbers. See Gnulib xstrtol function. */\n";
+ pr "static const char *xstrtol_suffixes = \"0kKMGTPEZY\";\n";
+ pr "\n";
(* list_commands function, which implements guestfish -h *)
pr "void list_commands (void)\n";
pr " strtol_error xerr;\n";
pr " %s r;\n" fntyp;
pr "\n";
- pr " xerr = %s (argv[%d], NULL, 0, &r, \"\");\n" fn i;
+ pr " xerr = %s (argv[%d], NULL, 0, &r, xstrtol_suffixes);\n" fn i;
pr " if (xerr != LONGINT_OK) {\n";
pr " fprintf (stderr,\n";
pr " _(\"%%s: %%s: invalid integer parameter (%%s returned %%d)\\n\"),\n";