Web lists-archives.com

Re: [PATCH] git-prompt: fix reading files with windows line endings

Hi Johannes,

On 30 Nov 2017 01:21, Johannes Schindelin wrote:
> On Wed, 29 Nov 2017, Robert Abel wrote:
>> This means that it should be okay to just do
>>> test -r "$f" && IFS=" \t\r\n" read "$@" < "$f"
> I am afraid that this won't work: when I call

I managed to trick myself with that one, yes...
Apparently I had already converted my HEAD back to Unix line endings.

However, I noticed that the behavior of read is apparently
ambiguous for the last (or a single) variable:

>From POSIX.1-2008:
> If there are fewer vars than fields, the last var shall be set to a
> value comprising the following elements:
> - The field that corresponds to the last var in the normal assignment
>   sequence described above
> - The delimiter(s) that follow the field corresponding to the last var
> - The remaining fields and their delimiters, with trailing IFS white
>   space ignored

I read that last "ignored" as "trailing IFS white space shall not be
appended". Apparently, people implementing read read it as "trailing
IFS while space shall not be processed further"

Thus, the behavior for trailing IFS white space is different in
case of one or two variables:

    printf '123 456\r\n' | while IFS=$' \t\r\n' read foo bar
        printf 'foo: %s' "$foo" | hexdump -C
        printf 'bar: %s' "$bar" | hexdump -C

This works as expected trimming the trailing \r:
    00000000  66 6f 6f 3a 20 31 32 33                           |foo: 123|
    00000000  62 61 72 3a 20 34 35 36                           |bar: 456|

While doing the same just reading a single variable

    printf '123 456\r\n' | while IFS=$' \t\r\n' read foo
        printf 'foo: %s' "$foo" | hexdump -C
        printf 'bar: %s' "$bar" | hexdump -C


    00000000  66 6f 6f 3a 20 31 32 33  20 34 35 36 0d           |foo:
123 456.|
    00000000  62 61 72 3a 20                                    |bar: |

Notice the 0d at the end of foo, which didn't get trimmed.

So reading a dummy variable along with the actual content variable
works for git-prompt:

    __git_eread ()
        local f="$1"
        local dummy
        test -r "$f" && IFS=$'\r\n' read "$@" dummy < "$f"

I feel like this would be the most readable solution thus far.