diff --git a/ChangeLog b/ChangeLog index 733fad1de..51df27bf2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2013-10-17 BVK Chaitanya + + Added `tr' command support. + + * grub-core/commands/tr.c: New file. + * grub-core/Makefile.core.def: Build rules for new module. + + * tests/grub_cmd_tr.in: New test. + * Makefile.util.def: Build rules for new test. + 2013-10-17 Vladimir Testov * grub-core/gfxmenu/gui_progress_bar.c: Sanity checks added. diff --git a/Makefile.util.def b/Makefile.util.def index 145dabc5e..9d0638a90 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -857,6 +857,12 @@ script = { common = tests/grub_func_test.in; }; +script = { + testcase; + name = grub_cmd_tr; + common = tests/grub_cmd_tr.in; +}; + program = { testcase; name = example_unit_test; diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 8751adff8..e736e08b9 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -2128,3 +2128,8 @@ module = { name = testspeed; common = commands/testspeed.c; }; + +module = { + name = tr; + common = commands/tr.c; +}; diff --git a/grub-core/commands/tr.c b/grub-core/commands/tr.c new file mode 100644 index 000000000..adb292b55 --- /dev/null +++ b/grub-core/commands/tr.c @@ -0,0 +1,126 @@ +/* tr.c -- The tr command. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,2013 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static const struct grub_arg_option options[] = + { + { "set", 's', 0, N_("Variable name to update."), N_("VARNAME"), ARG_TYPE_STRING }, + { "upcase", 'U', 0, N_("Translate to upper case."), 0, 0 }, + { "downcase", 'D', 0, N_("Translate to lower case."), 0, 0 }, + { 0, 0, 0, 0, 0, 0 } + }; + +static const char *letters_lowercase = "abcdefghijklmnopqrstuvwxyz"; +static const char *letters_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +static grub_err_t +grub_cmd_tr (grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *var = 0; + const char *input = 0; + char *output = 0, *optr; + const char *s1 = 0; + const char *s2 = 0; + const char *iptr; + + /* Select the defaults from options. */ + if (ctxt->state[0].set) { + var = ctxt->state[0].arg; + input = grub_env_get (var); + } + + if (ctxt->state[1].set) { + s1 = letters_lowercase; + s2 = letters_uppercase; + } + + if (ctxt->state[2].set) { + s1 = letters_uppercase; + s2 = letters_lowercase; + } + + /* Check for arguments and update the defaults. */ + if (argc == 1) + input = args[0]; + + else if (argc == 2) { + s1 = args[0]; + s2 = args[1]; + + } else if (argc == 3) { + s1 = args[0]; + s2 = args[1]; + input = args[2]; + + } else if (argc > 3) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "too many parameters"); + + if (argc <= 0 && (!s1 || !s2 || !input)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing parameters"); + + if (grub_strlen (s1) != grub_strlen (s2)) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "set sizes did not match"); + + /* Translate input into output buffer. */ + + output = grub_malloc (grub_strlen (input) + 1); + if (! output) + return grub_errno; + + optr = output; + for (iptr = input; *iptr; iptr++) + { + char *p = grub_strchr (s1, *iptr); + if (p) + *optr++ = s2[p - s1]; + else + *optr++ = *iptr; + } + *optr = '\0'; + + if (ctxt->state[0].set) + grub_env_set (var, output); + else + grub_printf ("%s\n", output); + + grub_free (output); + return GRUB_ERR_NONE; +} + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT(tr) +{ + cmd = grub_register_extcmd ("tr", grub_cmd_tr, 0, N_("[OPTIONS] [SET1] [SET2] [STRING]"), + N_("Translate SET1 characters to SET2 in STRING."), options); +} + +GRUB_MOD_FINI(tr) +{ + grub_unregister_extcmd (cmd); +} diff --git a/tests/grub_cmd_tr.in b/tests/grub_cmd_tr.in new file mode 100644 index 000000000..3fb15e35c --- /dev/null +++ b/tests/grub_cmd_tr.in @@ -0,0 +1,62 @@ +#! /bin/bash -e + +# Run GRUB script in a Qemu instance +# Copyright (C) 2010 Free Software Foundation, Inc. +# +# GRUB 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. +# +# GRUB 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 GRUB. If not, see . + +# +# Translating a string argument +# +cmd='tr 12345 abcde a1b2c3d4e5' +v=`echo "$cmd" | @builddir@/grub-shell` +if test "$v" != aabbccddee; then echo "error: $cmd [$v]" >&2; exit 1; fi + +cmd='tr -U abcdABCD' +v=`echo "$cmd" | @builddir@/grub-shell` +if test "$v" != ABCDABCD; then echo "error: $cmd [$v]" >&2; exit 1; fi + +cmd='tr -D ABCDabcd' +v=`echo "$cmd" | @builddir@/grub-shell` +if test "$v" != abcdabcd; then echo "error: $cmd [$v]" >&2; exit 1; fi + +# +# Translating a variable value +# +cmd='foo=12345678; tr -s foo 1234 abcd; echo $foo' +v=`echo "$cmd" | @builddir@/grub-shell` +if test "$v" != abcd5678; then echo "error: $cmd [$v]" >&2; exit 1; fi + +cmd='foo=abcdEFGH; tr -U -s foo; echo $foo' +v=`echo "$cmd" | @builddir@/grub-shell` +if test "$v" != ABCDEFGH; then echo "error: $cmd [$v]" >&2; exit 1; fi + +cmd='foo=abcdEFGH; tr -D -s foo; echo $foo' +v=`echo "$cmd" | @builddir@/grub-shell` +if test "$v" != abcdefgh; then echo "error: $cmd [$v]" >&2; exit 1; fi + +# +# Setting a variable from string argument +# +cmd='foo=12345678; tr -s foo 1234 abcd a1b2c3d4e5; echo $foo' +v=`echo "$cmd" | @builddir@/grub-shell` +if test "$v" != aabbccdde5; then echo "error: $cmd [$v]" >&2; exit 1; fi + +cmd='foo=abcdEFGH; tr -U -s foo xyz; echo $foo' +v=`echo "$cmd" | @builddir@/grub-shell` +if test "$v" != XYZ; then echo "error: $cmd [$v]" >&2; exit 1; fi + +cmd='foo=abcdEFGH; tr -D -s foo XYZ; echo $foo' +v=`echo "$cmd" | @builddir@/grub-shell` +if test "$v" != xyz; then echo "error: $cmd [$v]" >&2; exit 1; fi