[Libguestfs] [PATCH 1/4] fish: Allow suffixes on number parameters (eg. 1M)
Richard W.M. Jones
rjones at redhat.com
Fri May 21 13:52:32 UTC 2010
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
New in Fedora 11: Fedora Windows cross-compiler. Compile Windows
programs, test, and build Windows installers. Over 70 libraries supprt'd
http://fedoraproject.org/wiki/MinGW http://www.annexia.org/fedora_mingw
-------------- next part --------------
>From 5e1aff7856f721bf5737815a5b65c0de23ab0b0c Mon Sep 17 00:00:00 2001
From: Richard Jones <rjones at redhat.com>
Date: Fri, 21 May 2010 13:07:05 +0100
Subject: [PATCH 1/4] fish: Allow suffixes on number parameters (eg. 1M)
This small change uses the gnulib xstrtoll functionality to
enable suffixes on integer parameters in guestfish. For example:
truncate-size /file 1G
(previously you would have had to given the full number).
This also applies to the 'alloc' and 'sparse' commands (and
indirectly to the -N option). The specification for these commands
has changed slightly, in that 'alloc foo 1MB' would now use SI
units, allocating 1000000 bytes instead of a true megabyte. All
existing uses would use 'alloc foo 1M' which still allocates true
megabytes.
---
fish/alloc.c | 34 ++-----
fish/fish.c | 24 +----
fish/guestfish.pod | 162 ++++++++++++++++++--------------
regressions/rhbz557655-expected.stderr | 2 -
regressions/rhbz557655.sh | 6 +-
src/generator.ml | 5 +-
6 files changed, 113 insertions(+), 120 deletions(-)
diff --git a/fish/alloc.c b/fish/alloc.c
index f91c5bb..7533741 100644
--- a/fish/alloc.c
+++ b/fish/alloc.c
@@ -26,6 +26,8 @@
#include <inttypes.h>
#include <errno.h>
+#include "xstrtol.h"
+
#include "fish.h"
int
@@ -145,30 +147,14 @@ alloc_disk (const char *filename, const char *size_str, int add, int sparse)
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;
}
diff --git a/fish/fish.c b/fish/fish.c
index a32ed4d..d38d1c1 100644
--- a/fish/fish.c
+++ b/fish/fish.c
@@ -1069,16 +1069,8 @@ display_builtin_command (const char *cmd)
"\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"
@@ -1168,16 +1160,8 @@ display_builtin_command (const char *cmd)
"\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"
diff --git a/fish/guestfish.pod b/fish/guestfish.pod
index 274f1d4..a6d341e 100644
--- a/fish/guestfish.pod
+++ b/fish/guestfish.pod
@@ -320,9 +320,97 @@ must be escaped with a backslash.
=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
@@ -600,39 +688,7 @@ so it can be further examined.
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
@@ -727,39 +783,7 @@ danger you could run out of real disk space during a write operation.
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
diff --git a/regressions/rhbz557655-expected.stderr b/regressions/rhbz557655-expected.stderr
index c8e02f5..e570cf3 100644
--- a/regressions/rhbz557655-expected.stderr
+++ b/regressions/rhbz557655-expected.stderr
@@ -5,10 +5,8 @@ set-memsize: memsize: integer out of range
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)
diff --git a/regressions/rhbz557655.sh b/regressions/rhbz557655.sh
index 228b498..2306147 100755
--- a/regressions/rhbz557655.sh
+++ b/regressions/rhbz557655.sh
@@ -45,7 +45,6 @@ get-memsize
-set-memsize 07777770000000000000
-set-memsize ABC
-set-memsize 09
--set-memsize 123K
-set-memsize 123L
EOF
@@ -69,7 +68,6 @@ filesize /test
# these should all provoke parse errors:
-truncate-size /test ABC
-truncate-size /test 09
--truncate-size /test 123K
-truncate-size /test 123L
EOF
@@ -82,6 +80,6 @@ grep -E 'set[-_]memsize|truncate[-_]size' test.err~ |
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
diff --git a/src/generator.ml b/src/generator.ml
index d4ef81a..aca56a8 100755
--- a/src/generator.ml
+++ b/src/generator.ml
@@ -7456,6 +7456,9 @@ and generate_fish_cmds () =
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";
@@ -7674,7 +7677,7 @@ and generate_fish_cmds () =
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";
--
1.6.6.1
More information about the Libguestfs
mailing list