diff mbox

[committed] BZ #18409: Remove a trailing `\' in make-syscalls.sh

Message ID 5554F3B4.3050404@linaro.org
State New
Headers show

Commit Message

Adhemerval Zanella Netto May 14, 2015, 7:12 p.m. UTC
On 14-05-2015 15:08, H.J. Lu wrote:
> On Thu, May 14, 2015 at 11:03 AM, Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>>
>>
>> On 13-05-2015 16:34, H.J. Lu wrote:
>>> On Wed, May 13, 2015 at 12:30 PM, Adhemerval Zanella
>>> <adhemerval.zanella@linaro.org> wrote:
>>>> Hi
>>>>
>>>> On 13-05-2015 13:20, H.J. Lu wrote:
>>>>> commit c14874927b499ddfdbb03745bb32bfc778b8595f
>>>>> Author: Roland McGrath <roland@hack.frob.com>
>>>>> Date:   Tue May 22 16:00:50 2012 -0700
>>>>>
>>>>>     syscalls.list support for vDSO IFUNCs, use it for x32 gettimeofday and time.
>>>>>
>>>>> added
>>>>>
>>>>> \$(foreach p,\$(sysd-rules-targets),\$(objpfx)\$(patsubst %,\$p,$file).os): \\
>>>>>                 \$(..)sysdeps/unix/make-syscalls.sh\
>>>>>         \$(make-target-directory)
>>>>>
>>>>> to sysdeps/unix/make-syscalls.sh which generates
>>>>>
>>>>> #### CALL=gettimeofday NUMBER=(0x40000000 + 96) ARGS=i:pP SOURCE=-
>>>>> ifeq (,$(filter gettimeofday,$(unix-syscalls)))
>>>>> unix-syscalls += gettimeofday
>>>>> $(foreach p,$(sysd-rules-targets),$(foreach
>>>>> o,$(object-suffixes-noshared),$(objpfx)$(patsubst
>>>>> %,$p,gettimeofday)$o)): \
>>>>>                 $(..)sysdeps/unix/make-syscalls.sh
>>>>>         $(make-target-directory)
>>>>>         (echo '#define SYSCALL_NAME gettimeofday'; \
>>>>>          echo '#define SYSCALL_NARGS 2'; \
>>>>>          echo '#define SYSCALL_SYMBOL __gettimeofday'; \
>>>>>          echo '#include <syscall-template.S>'; \
>>>>>          echo 'weak_alias (__gettimeofday, gettimeofday)'; \
>>>>>          echo 'libc_hidden_weak (gettimeofday)'; \
>>>>>         ) | $(compile-syscall) $(foreach p,$(patsubst
>>>>> %gettimeofday,%,$(basename $(@F))),$($(p)CPPFLAGS))
>>>>> $(foreach p,$(sysd-rules-targets),$(objpfx)$(patsubst %,$p,gettimeofday).os): \
>>>>>                 $(..)sysdeps/unix/make-syscalls.sh      $(make-target-directory)
>>>>>                                                   ^^^^^^^^^ Missing newline
>>>>>         (echo '#include <dl-vdso.h>'; \
>>>>>          echo 'extern void *__gettimeofday_ifunc (void) __asm
>>>>> ("__gettimeofday");'; \
>>>>>          echo 'void *'; \
>>>>>          echo '__gettimeofday_ifunc (void)'; \
>>>>>          echo '{'; \
>>>>>          echo '  PREPARE_VERSION_KNOWN (symver, LINUX_2_6);'; \
>>>>>          echo '  return _dl_vdso_vsym ("__vdso_gettimeofday", &symver);'; \
>>>>>          echo '}'; \
>>>>>          echo 'asm (".type __gettimeofday, %gnu_indirect_function");'; \
>>>>>          echo 'asm (".globl __GI___gettimeofday\n"'; \
>>>>>          echo '     "__GI___gettimeofday = __gettimeofday");'; \
>>>>>          echo 'weak_alias (__gettimeofday, gettimeofday)'; \
>>>>>          echo 'libc_hidden_weak (gettimeofday)'; \
>>>>>         ) | $(compile-stdin.c) $(foreach p,$(patsubst
>>>>> %gettimeofday,%,$(basename $(@F))),$($(p)CPPFLAGS))
>>>>> endif
>>>>>
>>>>> This only affected x32.  I checked in this patch after tested on
>>>>> x32.
>>>>>
>>>>> Adhemerval, can you check if your problem with dash in
>>>>>
>>>>> https://sourceware.org/ml/libc-alpha/2015-04/msg00277.html
>>>>>
>>>>> is fixed by this?
>>>>>
>>>>> Thanks.
>>>>
>>>> I have been testing another more complete fix pointed out by Joseph [1]
>>>> and it fixes the x32 build with dash issue I was seeing.  Shouldn't we
>>>> push this one?
>>>>
>>>> [1] https://sourceware.org/ml/libc-alpha/2015-02/msg00396.html
>>>
>>> Well, this part is the same as the one I checked in:
>>>
>>>  \$(foreach p,\$(sysd-rules-targets),\$(objpfx)\$(patsubst %,\$p,$file).os): \\
>>> - \$(..)sysdeps/unix/make-syscalls.sh\
>>> + \$(..)sysdeps/unix/make-syscalls.sh
>>>
>>> At minimum, that patch should be rebased.
>>>
>>
>> What about:
>>
>> diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
>> index 910a22c..12f664e 100644
>> --- a/sysdeps/unix/make-syscalls.sh
>> +++ b/sysdeps/unix/make-syscalls.sh
>> @@ -272,28 +272,33 @@ while read file srcfile caller syscall args strong weak; do
>>      vdso_symbol="${vdso_syscall%@*}"
>>      vdso_symver="${vdso_syscall#*@}"
>>      vdso_symver=`echo "$vdso_symver" | sed 's/\./_/g'`
>> -    echo "\
>> +    cat <<EOF
>> +
>>  \$(foreach p,\$(sysd-rules-targets),\$(objpfx)\$(patsubst %,\$p,$file).os): \\
>>                 \$(..)sysdeps/unix/make-syscalls.sh
>>         \$(make-target-directory)
>>         (echo '#include <dl-vdso.h>'; \\
>> -        echo 'extern void *${strong}_ifunc (void) __asm (\"${strong}\");'; \\
>> +        echo 'extern void *${strong}_ifunc (void) __asm ("${strong}");'; \\
>>          echo 'void *'; \\
>>          echo '${strong}_ifunc (void)'; \\
>>          echo '{'; \\
>>          echo '  PREPARE_VERSION_KNOWN (symver, ${vdso_symver});'; \\
>> -        echo '  return _dl_vdso_vsym (\"${vdso_symbol}\", &symver);'; \\
>> +        echo '  return _dl_vdso_vsym ("${vdso_symbol}", &symver);'; \\
>>          echo '}'; \\
>> -        echo 'asm (\".type ${strong}, %gnu_indirect_function\");'; \\"
>> +        echo 'asm (".type ${strong}, %gnu_indirect_function");'; \\
>> +EOF
>>      # This is doing "libc_hidden_def (${strong})", but the compiler
>>      # doesn't know that we've defined ${strong} in the same file, so
>>      # we can't do it the normal way.
>> -    echo "\
>> -        echo 'asm (\".globl __GI_${strong}\\n\"'; \\
>> -        echo '     \"__GI_${strong} = ${strong}\");'; \\"
>> +    cat <<EOF
>> +        echo 'asm (".globl __GI_${strong}");'; \\
>> +        echo 'asm ("__GI_${strong} = ${strong}");'; \\
>> +EOF
>>      emit_weak_aliases
>> -    echo '     ) | $(compile-stdin.c) '"\
>> -\$(foreach p,\$(patsubst %$file,%,\$(basename \$(@F))),\$(\$(p)CPPFLAGS))"
>> +    cat <<EOF
>> +       ) | \$(compile-stdin.c) \
>> +\$(foreach p,\$(patsubst %$file,%,\$(basename \$(@F))),\$(\$(p)CPPFLAGS))
>> +EOF
>>    fi
>>
>>    if test $shared_only = t; then
>>
>> I checked builds for x86_64, i386, x32, and aarch64 for both dash and bash.
> 
> This only affects x32.  Please show the output of diff -up between
> 
> 1. The old x32 sysd-syscalls under bash and the new x32
> sysd-syscalls under bash.
> 2.  The new x32 sysd-syscalls under bash and the new x32
> sysd-syscalls under dash.
> 

The master still do not build for x32 on my setup with dash (ubuntu 14.04):

(echo '#include <dl-vdso.h>'; \
         echo 'extern void *time_ifunc (void) __asm ("time");'; \
         echo 'void *'; \
         echo 'time_ifunc (void)'; \
         echo '{'; \
         echo '  PREPARE_VERSION_KNOWN (symver, LINUX_2_6);'; \
         echo '  return _dl_vdso_vsym ("__vdso_time", &symver);'; \
         echo '}'; \
         echo 'asm (".type time, %gnu_indirect_function");'; \
         echo 'asm (".globl __GI_time
/bin/sh: 10: Syntax error: Unterminated quoted string

And it build with the modifications I proposed.  The differences using bash
with and without the patch are:

$ diff -pu /tmp/master.bash /tmp/patch.bash

Comments

H.J. Lu May 14, 2015, 7:34 p.m. UTC | #1
On Thu, May 14, 2015 at 12:12 PM, Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
>
>
> On 14-05-2015 15:08, H.J. Lu wrote:
>> On Thu, May 14, 2015 at 11:03 AM, Adhemerval Zanella
>> <adhemerval.zanella@linaro.org> wrote:
>>>
>>>
>>> On 13-05-2015 16:34, H.J. Lu wrote:
>>>> On Wed, May 13, 2015 at 12:30 PM, Adhemerval Zanella
>>>> <adhemerval.zanella@linaro.org> wrote:
>>>>> Hi
>>>>>
>>>>> On 13-05-2015 13:20, H.J. Lu wrote:
>>>>>> commit c14874927b499ddfdbb03745bb32bfc778b8595f
>>>>>> Author: Roland McGrath <roland@hack.frob.com>
>>>>>> Date:   Tue May 22 16:00:50 2012 -0700
>>>>>>
>>>>>>     syscalls.list support for vDSO IFUNCs, use it for x32 gettimeofday and time.
>>>>>>
>>>>>> added
>>>>>>
>>>>>> \$(foreach p,\$(sysd-rules-targets),\$(objpfx)\$(patsubst %,\$p,$file).os): \\
>>>>>>                 \$(..)sysdeps/unix/make-syscalls.sh\
>>>>>>         \$(make-target-directory)
>>>>>>
>>>>>> to sysdeps/unix/make-syscalls.sh which generates
>>>>>>
>>>>>> #### CALL=gettimeofday NUMBER=(0x40000000 + 96) ARGS=i:pP SOURCE=-
>>>>>> ifeq (,$(filter gettimeofday,$(unix-syscalls)))
>>>>>> unix-syscalls += gettimeofday
>>>>>> $(foreach p,$(sysd-rules-targets),$(foreach
>>>>>> o,$(object-suffixes-noshared),$(objpfx)$(patsubst
>>>>>> %,$p,gettimeofday)$o)): \
>>>>>>                 $(..)sysdeps/unix/make-syscalls.sh
>>>>>>         $(make-target-directory)
>>>>>>         (echo '#define SYSCALL_NAME gettimeofday'; \
>>>>>>          echo '#define SYSCALL_NARGS 2'; \
>>>>>>          echo '#define SYSCALL_SYMBOL __gettimeofday'; \
>>>>>>          echo '#include <syscall-template.S>'; \
>>>>>>          echo 'weak_alias (__gettimeofday, gettimeofday)'; \
>>>>>>          echo 'libc_hidden_weak (gettimeofday)'; \
>>>>>>         ) | $(compile-syscall) $(foreach p,$(patsubst
>>>>>> %gettimeofday,%,$(basename $(@F))),$($(p)CPPFLAGS))
>>>>>> $(foreach p,$(sysd-rules-targets),$(objpfx)$(patsubst %,$p,gettimeofday).os): \
>>>>>>                 $(..)sysdeps/unix/make-syscalls.sh      $(make-target-directory)
>>>>>>                                                   ^^^^^^^^^ Missing newline
>>>>>>         (echo '#include <dl-vdso.h>'; \
>>>>>>          echo 'extern void *__gettimeofday_ifunc (void) __asm
>>>>>> ("__gettimeofday");'; \
>>>>>>          echo 'void *'; \
>>>>>>          echo '__gettimeofday_ifunc (void)'; \
>>>>>>          echo '{'; \
>>>>>>          echo '  PREPARE_VERSION_KNOWN (symver, LINUX_2_6);'; \
>>>>>>          echo '  return _dl_vdso_vsym ("__vdso_gettimeofday", &symver);'; \
>>>>>>          echo '}'; \
>>>>>>          echo 'asm (".type __gettimeofday, %gnu_indirect_function");'; \
>>>>>>          echo 'asm (".globl __GI___gettimeofday\n"'; \
>>>>>>          echo '     "__GI___gettimeofday = __gettimeofday");'; \
>>>>>>          echo 'weak_alias (__gettimeofday, gettimeofday)'; \
>>>>>>          echo 'libc_hidden_weak (gettimeofday)'; \
>>>>>>         ) | $(compile-stdin.c) $(foreach p,$(patsubst
>>>>>> %gettimeofday,%,$(basename $(@F))),$($(p)CPPFLAGS))
>>>>>> endif
>>>>>>
>>>>>> This only affected x32.  I checked in this patch after tested on
>>>>>> x32.
>>>>>>
>>>>>> Adhemerval, can you check if your problem with dash in
>>>>>>
>>>>>> https://sourceware.org/ml/libc-alpha/2015-04/msg00277.html
>>>>>>
>>>>>> is fixed by this?
>>>>>>
>>>>>> Thanks.
>>>>>
>>>>> I have been testing another more complete fix pointed out by Joseph [1]
>>>>> and it fixes the x32 build with dash issue I was seeing.  Shouldn't we
>>>>> push this one?
>>>>>
>>>>> [1] https://sourceware.org/ml/libc-alpha/2015-02/msg00396.html
>>>>
>>>> Well, this part is the same as the one I checked in:
>>>>
>>>>  \$(foreach p,\$(sysd-rules-targets),\$(objpfx)\$(patsubst %,\$p,$file).os): \\
>>>> - \$(..)sysdeps/unix/make-syscalls.sh\
>>>> + \$(..)sysdeps/unix/make-syscalls.sh
>>>>
>>>> At minimum, that patch should be rebased.
>>>>
>>>
>>> What about:
>>>
>>> diff --git a/sysdeps/unix/make-syscalls.sh b/sysdeps/unix/make-syscalls.sh
>>> index 910a22c..12f664e 100644
>>> --- a/sysdeps/unix/make-syscalls.sh
>>> +++ b/sysdeps/unix/make-syscalls.sh
>>> @@ -272,28 +272,33 @@ while read file srcfile caller syscall args strong weak; do
>>>      vdso_symbol="${vdso_syscall%@*}"
>>>      vdso_symver="${vdso_syscall#*@}"
>>>      vdso_symver=`echo "$vdso_symver" | sed 's/\./_/g'`
>>> -    echo "\
>>> +    cat <<EOF
>>> +
>>>  \$(foreach p,\$(sysd-rules-targets),\$(objpfx)\$(patsubst %,\$p,$file).os): \\
>>>                 \$(..)sysdeps/unix/make-syscalls.sh
>>>         \$(make-target-directory)
>>>         (echo '#include <dl-vdso.h>'; \\
>>> -        echo 'extern void *${strong}_ifunc (void) __asm (\"${strong}\");'; \\
>>> +        echo 'extern void *${strong}_ifunc (void) __asm ("${strong}");'; \\
>>>          echo 'void *'; \\
>>>          echo '${strong}_ifunc (void)'; \\
>>>          echo '{'; \\
>>>          echo '  PREPARE_VERSION_KNOWN (symver, ${vdso_symver});'; \\
>>> -        echo '  return _dl_vdso_vsym (\"${vdso_symbol}\", &symver);'; \\
>>> +        echo '  return _dl_vdso_vsym ("${vdso_symbol}", &symver);'; \\
>>>          echo '}'; \\
>>> -        echo 'asm (\".type ${strong}, %gnu_indirect_function\");'; \\"
>>> +        echo 'asm (".type ${strong}, %gnu_indirect_function");'; \\
>>> +EOF
>>>      # This is doing "libc_hidden_def (${strong})", but the compiler
>>>      # doesn't know that we've defined ${strong} in the same file, so
>>>      # we can't do it the normal way.
>>> -    echo "\
>>> -        echo 'asm (\".globl __GI_${strong}\\n\"'; \\
>>> -        echo '     \"__GI_${strong} = ${strong}\");'; \\"
>>> +    cat <<EOF
>>> +        echo 'asm (".globl __GI_${strong}");'; \\
>>> +        echo 'asm ("__GI_${strong} = ${strong}");'; \\
>>> +EOF
>>>      emit_weak_aliases
>>> -    echo '     ) | $(compile-stdin.c) '"\
>>> -\$(foreach p,\$(patsubst %$file,%,\$(basename \$(@F))),\$(\$(p)CPPFLAGS))"
>>> +    cat <<EOF
>>> +       ) | \$(compile-stdin.c) \
>>> +\$(foreach p,\$(patsubst %$file,%,\$(basename \$(@F))),\$(\$(p)CPPFLAGS))
>>> +EOF
>>>    fi
>>>
>>>    if test $shared_only = t; then
>>>
>>> I checked builds for x86_64, i386, x32, and aarch64 for both dash and bash.
>>
>> This only affects x32.  Please show the output of diff -up between
>>
>> 1. The old x32 sysd-syscalls under bash and the new x32
>> sysd-syscalls under bash.
>> 2.  The new x32 sysd-syscalls under bash and the new x32
>> sysd-syscalls under dash.
>>
>
> The master still do not build for x32 on my setup with dash (ubuntu 14.04):
>
> (echo '#include <dl-vdso.h>'; \
>          echo 'extern void *time_ifunc (void) __asm ("time");'; \
>          echo 'void *'; \
>          echo 'time_ifunc (void)'; \
>          echo '{'; \
>          echo '  PREPARE_VERSION_KNOWN (symver, LINUX_2_6);'; \
>          echo '  return _dl_vdso_vsym ("__vdso_time", &symver);'; \
>          echo '}'; \
>          echo 'asm (".type time, %gnu_indirect_function");'; \
>          echo 'asm (".globl __GI_time
> /bin/sh: 10: Syntax error: Unterminated quoted string
>
> And it build with the modifications I proposed.  The differences using bash
> with and without the patch are:
>
> $ diff -pu /tmp/master.bash /tmp/patch.bash
> --- /tmp/master.bash    2015-05-14 16:01:06.986718272 -0300
> +++ /tmp/patch.bash     2015-05-14 16:07:41.450731250 -0300
> @@ -36,6 +36,7 @@ $(foreach p,$(sysd-rules-targets),$(fore
>          echo 'weak_alias (__gettimeofday, gettimeofday)'; \
>          echo 'libc_hidden_weak (gettimeofday)'; \
>         ) | $(compile-syscall) $(foreach p,$(patsubst %gettimeofday,%,$(basename $(@F))),$($(p)CPPFLAGS))
> +
>  $(foreach p,$(sysd-rules-targets),$(objpfx)$(patsubst %,$p,gettimeofday).os): \
>                 $(..)sysdeps/unix/make-syscalls.sh
>         $(make-target-directory)
> @@ -48,8 +49,8 @@ $(foreach p,$(sysd-rules-targets),$(objp
>          echo '  return _dl_vdso_vsym ("__vdso_gettimeofday", &symver);'; \
>          echo '}'; \
>          echo 'asm (".type __gettimeofday, %gnu_indirect_function");'; \
> -        echo 'asm (".globl __GI___gettimeofday\n"'; \
> -        echo '     "__GI___gettimeofday = __gettimeofday");'; \
> +        echo 'asm (".globl __GI___gettimeofday");'; \
> +        echo 'asm ("__GI___gettimeofday = __gettimeofday");'; \
>          echo 'weak_alias (__gettimeofday, gettimeofday)'; \
>          echo 'libc_hidden_weak (gettimeofday)'; \
>         ) | $(compile-stdin.c) $(foreach p,$(patsubst %gettimeofday,%,$(basename $(@F))),$($(p)CPPFLAGS))
> @@ -123,6 +124,7 @@ $(foreach p,$(sysd-rules-targets),$(fore
>          echo '#define SYSCALL_ERRVAL 0'; \
>          echo '#include <syscall-template.S>'; \
>         ) | $(compile-syscall) $(foreach p,$(patsubst %time,%,$(basename $(@F))),$($(p)CPPFLAGS))
> +
>  $(foreach p,$(sysd-rules-targets),$(objpfx)$(patsubst %,$p,time).os): \
>                 $(..)sysdeps/unix/make-syscalls.sh
>         $(make-target-directory)
> @@ -135,8 +137,8 @@ $(foreach p,$(sysd-rules-targets),$(objp
>          echo '  return _dl_vdso_vsym ("__vdso_time", &symver);'; \
>          echo '}'; \
>          echo 'asm (".type time, %gnu_indirect_function");'; \
> -        echo 'asm (".globl __GI_time\n"'; \
> -        echo '     "__GI_time = time");'; \
> +        echo 'asm (".globl __GI_time");'; \
> +        echo 'asm ("__GI_time = time");'; \
>         ) | $(compile-stdin.c) $(foreach p,$(patsubst %time,%,$(basename $(@F))),$($(p)CPPFLAGS))
>  endif

Looks good to me.  Please check it in.

Thanks.
Joseph Myers May 14, 2015, 9:22 p.m. UTC | #2
Please mention [BZ #16704] in the ChangeLog entry for your latest commit 
(and if the build with dash for x32 now works, also mention that bug 
number in NEWS and close it as fixed).
diff mbox

Patch

--- /tmp/master.bash    2015-05-14 16:01:06.986718272 -0300
+++ /tmp/patch.bash     2015-05-14 16:07:41.450731250 -0300
@@ -36,6 +36,7 @@  $(foreach p,$(sysd-rules-targets),$(fore
         echo 'weak_alias (__gettimeofday, gettimeofday)'; \
         echo 'libc_hidden_weak (gettimeofday)'; \
        ) | $(compile-syscall) $(foreach p,$(patsubst %gettimeofday,%,$(basename $(@F))),$($(p)CPPFLAGS))
+
 $(foreach p,$(sysd-rules-targets),$(objpfx)$(patsubst %,$p,gettimeofday).os): \
                $(..)sysdeps/unix/make-syscalls.sh
        $(make-target-directory)
@@ -48,8 +49,8 @@  $(foreach p,$(sysd-rules-targets),$(objp
         echo '  return _dl_vdso_vsym ("__vdso_gettimeofday", &symver);'; \
         echo '}'; \
         echo 'asm (".type __gettimeofday, %gnu_indirect_function");'; \
-        echo 'asm (".globl __GI___gettimeofday\n"'; \
-        echo '     "__GI___gettimeofday = __gettimeofday");'; \
+        echo 'asm (".globl __GI___gettimeofday");'; \
+        echo 'asm ("__GI___gettimeofday = __gettimeofday");'; \
         echo 'weak_alias (__gettimeofday, gettimeofday)'; \
         echo 'libc_hidden_weak (gettimeofday)'; \
        ) | $(compile-stdin.c) $(foreach p,$(patsubst %gettimeofday,%,$(basename $(@F))),$($(p)CPPFLAGS))
@@ -123,6 +124,7 @@  $(foreach p,$(sysd-rules-targets),$(fore
         echo '#define SYSCALL_ERRVAL 0'; \
         echo '#include <syscall-template.S>'; \
        ) | $(compile-syscall) $(foreach p,$(patsubst %time,%,$(basename $(@F))),$($(p)CPPFLAGS))
+
 $(foreach p,$(sysd-rules-targets),$(objpfx)$(patsubst %,$p,time).os): \
                $(..)sysdeps/unix/make-syscalls.sh
        $(make-target-directory)
@@ -135,8 +137,8 @@  $(foreach p,$(sysd-rules-targets),$(objp
         echo '  return _dl_vdso_vsym ("__vdso_time", &symver);'; \
         echo '}'; \
         echo 'asm (".type time, %gnu_indirect_function");'; \
-        echo 'asm (".globl __GI_time\n"'; \
-        echo '     "__GI_time = time");'; \
+        echo 'asm (".globl __GI_time");'; \
+        echo 'asm ("__GI_time = time");'; \
        ) | $(compile-stdin.c) $(foreach p,$(patsubst %time,%,$(basename $(@F))),$($(p)CPPFLAGS))
 endif