From: Richard Jones Date: Fri, 21 May 2010 12:07:05 +0000 (+0100) Subject: fish: Allow suffixes on number parameters (eg. 1M) X-Git-Tag: 1.3.14~9 X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=commitdiff_plain;h=5e1aff7856f721bf5737815a5b65c0de23ab0b0c 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. --- 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 #include +#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 means a number):\n" - " number of kilobytes\n" - " eg: 1440 standard 3.5\" floppy\n" - " K or KB number of kilobytes\n" - " M or MB number of megabytes\n" - " G or GB number of gigabytes\n" - " T or TB number of terabytes\n" - " P or PB number of petabytes\n" - " E or EB number of exabytes\n" - " 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 [ ...]\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 means a number):\n" - " number of kilobytes\n" - " eg: 1440 standard 3.5\" floppy\n" - " K or KB number of kilobytes\n" - " M or MB number of megabytes\n" - " G or GB number of gigabytes\n" - " T or TB number of terabytes\n" - " P or PB number of petabytes\n" - " E or EB number of exabytes\n" - " 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 [ ...]\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 or B or B + +The size in kilobytes (multiplied by 1024). + +=item B + +The size in SI 1000 byte units. + +=item B or B + +The size in megabytes (multiplied by 1048576). + +=item B + +The size in SI 1000000 byte units. + +=item B or B + +The size in gigabytes (multiplied by 2**30). + +=item B + +The size in SI 10**9 byte units. + +=item B or B + +The size in terabytes (multiplied by 2**40). + +=item B + +The size in SI 10**12 byte units. + +=item B

or B + +The size in petabytes (multiplied by 2**50). + +=item B + +The size in SI 10**15 byte units. + +=item B or B + +The size in exabytes (multiplied by 2**60). + +=item B + +The size in SI 10**18 byte units. + +=item B or B + +The size in zettabytes (multiplied by 2**70). + +=item B + +The size in SI 10**21 byte units. + +=item B or B + +The size in yottabytes (multiplied by 2**80). + +=item B + +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 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 utility. -Size can be specified (where C means a number): - -=over 4 - -=item C or CK or CKB - -number of kilobytes, eg: C<1440> = standard 3.5in floppy - -=item CM or CMB - -number of megabytes - -=item CG or CGB - -number of gigabytes - -=item CT or CTB - -number of terabytes - -=item CP or CPB - -number of petabytes - -=item CE or CEB - -number of exabytes - -=item Csects - -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 utility. -Size can be specified (where C means a number): - -=over 4 - -=item C or CK or CKB - -number of kilobytes, eg: C<1440> = standard 3.5in floppy - -=item CM or CMB - -number of megabytes - -=item CG or CGB - -number of gigabytes - -=item CT or CTB - -number of terabytes - -=item CP or CPB - -number of petabytes - -=item CE or CEB - -number of exabytes - -=item Csects - -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";