4

I am trying to understand the following code snippet.

host_cpu='i386'

case "$host_cpu" in
   i[[3456]]86)
       echo "host_cpu=i386"
   ;;
   x86_64)
       echo "host_cpu=x86_64"
   ;;
   *)
       echo "AC_MSG_ERROR([unsupported CPU type]) "
   ;;
esac

I added the variable host_cpu='i386' myself to test the code and it switched to the third case of echo "AC_MSG_ERROR([unsupported CPU type]) ".

If I change the double bracket in i[[3456]]86) to a single bracket as in i[3456]86), it switches to the first option yielding i386. This seems correct to me.

I understand that [ and [[ are the test options. The test condition doesn't seem to apply here as the switch cases are expecting a character to be outputted. So I'm assuming for bash to pick it up as a test condition, it needs to be separated by a space as in [ a < b ] or [[ a << b ]]. Because there are no spaces in these case statement, it'll be treated as a regular expression. Is this correct?

So my question is why was the double square bracket was used here by the code writer? It didn't work when I tried to run the code, so what was their intention.

Note: The code was taken from a configure.ac in the GRUB source code.

Also the $host_cpu and host_cpu=i386 line seem unnecessary, can you explain why the writer would have done this:

AC_CANONICAL_HOST

case "$host_cpu" in
    i[[3456]]86) host_cpu=i386 ;;
    x86_64) host_cpu=x86_64 ;;
    *) AC_MSG_ERROR([unsupported CPU type]) ;;
esac

AC_SUBST(host_cpu)
AC_SUBST(host_vendor)

I'm thinking of using AC_SUBST($host_cpu). Why wouldn't you do it this way?

1
  • 2
    Looks like a bug. I suggest you submit a pull request. And no, it's not a regular expression; it's pattern matching, which works the same as file globs.
    – Wildcard
    Oct 4, 2018 at 1:56

1 Answer 1

9

If that's a from a configure.ac file, then it's not a pure shell script, but is an Autoconf script using M4, where [] are quote characters.:

To fully understand where proper quotation is important, you first need to know what the special characters are in Autoconf: ‘#’ introduces a comment inside which no macro expansion is performed, ‘,’ separates arguments, ‘[’ and ‘]’ are the quotes themselves, ‘(’ and ‘)’ (which M4 tries to match by pairs), and finally ‘$’ inside a macro definition.

Each time there can be a macro expansion, there is a quotation expansion, i.e., one level of quotes is stripped:

 int tab[10];
 ⇒int tab10;
 [int tab[10];]
 ⇒int tab[10];

That [[3456]] should be expanded by autoconf to [3456], which would be the correct output for use as a shell script.

7
  • 1
    Indeed - as one can verify by adding a minimal AC_INIT([foo]) to the top of the snippet and then executing autoconf snippet Oct 4, 2018 at 2:27
  • Okay, thanks. I've read about m4 and they used the quote characters ` and ' in those articles. So the must have changed the quotes in the configure.ac to treat [ and ] as quotes.
    – supmethods
    Oct 4, 2018 at 3:56
  • The link you provided use [ and ] as quotes. Does this depend on M4 version used?
    – supmethods
    Oct 4, 2018 at 4:01
  • @supmethods you can change the quote characters in M4, and it seems [ ] are set as quote characters in autoconf scripts. The default quote characters in M4 are `' , as you have seen.
    – muru
    Oct 4, 2018 at 4:17
  • I updated the post and would like to know the main purpose of the case statement. AC_CANONICAL_HOST computes the host_cpu, host_vendor, and host_os. Doesn't it mean that you don't need assignment of the variables (as in host_cpu=i386 and host_cpu=x86_64), and that you can simply do an "if $host_cpu is false then AC_MSG_ERROR([unsupported CPU type])"? host_cpu should already be set from AC_CANONICAL_HOST, so shell variable can be set straight away (AC_SUBST(host_cpu) without the assignment).
    – supmethods
    Oct 9, 2018 at 12:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .