On Sat, Jul 12, 2014 at 01:52:53AM +0900, Yi EungJun wrote:
> Add an Accept-Language header which indicates the user's preferred
> languages defined by $LANGUAGE, $LC_ALL, $LC_MESSAGES and $LANG.
>
> Examples:
> LANGUAGE= -> ""
> LANGUAGE=ko:en -> "Accept-Language: ko, en; q=0.9, *; q=0.1"
> LANGUAGE=ko LANG=en_US.UTF-8 -> "Accept-Language: ko, *; q=0.1"
> LANGUAGE= LANG=en_US.UTF-8 -> "Accept-Language: en-US, *; q=0.1"
>
> This gives git servers a chance to display remote error messages in
> the user's preferred language.
Thanks, this is looking much nicer. Most of my comments are on style:
> +static const char* get_preferred_languages() {
> + const char* retval;
A few style nits:
1. We usually put a function's opening brace on a new line.
2. We usually put the asterisk in a pointer declaration with the
variable name ("const char *retval"). This one appears elsewhere in
the patch.
3. This line seems to be indented with spaces instead of tabs.
> + retval = getenv("LANGUAGE");
> + if (retval != NULL && retval[0] != '\0')
> + return retval;
> +
> + retval = setlocale(LC_MESSAGES, NULL);
> + if (retval != NULL && retval[0] != '\0'
> + && strcmp(retval, "C") != 0
> + && strcmp(retval, "POSIX") != 0)
> + return retval;
More style nits: we usually avoid writing out explicit comparisons with
NULL (and often with zero). So I'd write this as:
if (retval && *retval &&
strcmp(retval, "C") &&
strcmp(retval, "POSIX"))
but I think the NULL one is the only one we usually enforce explicitly.
> + const char *p1, *p2, *p3;
I had trouble following the logic with these variable names. Is it
possible to give them more descriptive names?
> + /* Don't add Accept-Language header if no language is preferred. */
> + if (p1 == NULL || p1[0] == '\0') {
> + strbuf_release(&buf);
> + return headers;
> + }
No need to strbuf_release a buffer that hasn't been used (assigning
STRBUF_INIT does not count as use).
> + /* Count number of preferred languages to decide precision of q-factor
> */
> + for (p3 = p1; *p3 != '\0'; p3++) {
> + if (*p3 == ':') {
> + num_langs++;
> + }
> + }
Style: we usually omit braces for one-liners. So:
for (p3 = p1; *p3; p3++)
if (*p3 == ':')
num_langs++;
(and elsewhere).
> + /* Decide the precision for q-factor on number of preferred languages.
> */
> + if (num_langs + 1 > 100) { /* +1 is for '*' */
> + q_precision = 0.001;
> + q_format = "; q=%.3f";
> + } else if (num_langs + 1 > 10) { /* +1 is for '*' */
> + q_precision = 0.01;
> + q_format = "; q=%.2f";
> + }
I don't mind this auto-precision too much, but I'm not sure it buys us
anything. We are still setting a hard-limit at 100, and it just means we
write "0.1" instead of "0.001" sometimes.
> + headers = curl_slist_append(headers, buf.buf);
> +
> + strbuf_release(&buf);
Do all versions of curl make a copy of buf.buf here?
I seem to recall that older versions want pointers passed to
curl_easy_setopt to stay around for the duration of the request (I do
not know about curl_slist, though).
> @@ -1020,6 +1143,8 @@ static int http_request(const char *url,
> fwrite_buffer);
> }
>
> + headers = add_accept_language(headers);
This means we do the whole parsing routine for each request we make (for
dumb-http, this can be quite a lot, though I suppose the parsing is not
especially expensive). Should we perhaps just cache the result in a
static strbuf? That would also make the pointer-lifetime issue above go
away.
> --- a/remote-curl.c
> +++ b/remote-curl.c
> @@ -946,6 +946,8 @@ int main(int argc, const char **argv)
> struct strbuf buf = STRBUF_INIT;
> int nongit;
>
> + git_setup_gettext();
Oops. We probably should have been doing this all along to localize the
messages on our side.
> +test_expect_success 'git client sends Accept-Language based on LANGUAGE,
> LC_ALL, LC_MESSAGES and LANG' '
> + test_must_fail env GIT_CURL_VERBOSE=1 LANGUAGE=ko_KR.UTF-8
> LC_ALL=de_DE.UTF-8 LC_MESSAGES=ja_JP.UTF-8 LANG=en_US.UTF-8 git clone
> "$HTTPD_URL/accept/language" 2>stderr &&
We usually try to avoid long lines (you can break them up with "\").
> + grep "^Accept-Language: ko-KR, \\*; q=0.1" stderr &&
I see you noticed the extra level of quoting necessary between v2 and
v3. :)
I wonder if these test cases might be more readable with a helper
function like:
check_language () {
echo "Accept-Language: $1" >expect &&
test_must_fail env \
GIT_CURL_VERBOSE=1 \
LANGUAGE=$2 \
LC_ALL=$3 \
LC_MESSAGES=$4 \
LANG=$5 \
git clone "$HTTPD_URL/accept/language" 2>stderr &&
grep -i ^Accept-Language: stderr >actual &&
test_cmp expect actual
}
which lets you write:
check_language "de-DE, *; q=0.1" "" de_DE.UTF-8 ja_JP.UTF-8 en_US.UTF-8
and so on. I dunno if that is more readable or not.
-Peff
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html