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?

  • 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 '18 at 1:56
8

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.

  • 1
    Indeed - as one can verify by adding a minimal AC_INIT([foo]) to the top of the snippet and then executing autoconf snippet – steeldriver Oct 4 '18 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 '18 at 3:56
  • The link you provided use [ and ] as quotes. Does this depend on M4 version used? – supmethods Oct 4 '18 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 '18 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 '18 at 12:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.