Skip to content

Commit 87eadf1

Browse files
committed
send: format floating-point numbers with the POSIX locale
Avoid locale-specific number formats (e.g. the comma is used as decimal separator in some locales). Closes #142
1 parent ce48272 commit 87eadf1

File tree

4 files changed

+58
-1
lines changed

4 files changed

+58
-1
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ libmpdclient 2.23 (not yet released)
66
- new sticker find api
77
- new subcommands for "tagtypes": "available", "reset"
88
* Support open end for mpd_search_add_window
9+
* format floating-point numbers with the POSIX localew
910

1011
libmpdclient 2.22 (2023/12/22)
1112
* drop the unmaintained Vala bindings

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ conf.set('DEFAULT_PORT', get_option('default_port'))
2323

2424
conf.set('HAVE_STRNDUP', cc.has_function('strndup', prefix: '#define _GNU_SOURCE\n#include <string.h>'))
2525
conf.set('HAVE_SETLOCALE', cc.has_function('setlocale', prefix: '#include <locale.h>'))
26+
conf.set('HAVE_USELOCALE', cc.has_function('uselocale', prefix: '#define _GNU_SOURCE\n#include <locale.h>'))
2627

2728
platform_deps = []
2829
if host_machine.system() == 'haiku'

src/player.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@
77
#include <mpd/response.h>
88
#include "isend.h"
99
#include "run.h"
10+
#include "config.h" // for HAVE_USELOCALE
1011

1112
#include <limits.h>
1213
#include <stdio.h>
1314

15+
#ifdef HAVE_USELOCALE
16+
#include <locale.h>
17+
#endif
18+
1419
bool
1520
mpd_send_current_song(struct mpd_connection *connection)
1621
{
@@ -196,12 +201,23 @@ bool
196201
mpd_send_seek_current(struct mpd_connection *connection,
197202
float t, bool relative)
198203
{
204+
#ifdef HAVE_USELOCALE
205+
// use the POSIX locale to format floating point numbers
206+
const locale_t my_locale = newlocale(LC_NUMERIC_MASK, "C", NULL);
207+
const locale_t old_locale = uselocale(my_locale);
208+
#endif
209+
199210
char ts[32];
200211
if (relative)
201212
snprintf(ts, sizeof(ts), "%+.3f", (double)t);
202213
else
203214
snprintf(ts, sizeof(ts), "%.3f", (double)t);
204215

216+
#ifdef HAVE_USELOCALE
217+
uselocale(old_locale);
218+
freelocale(my_locale);
219+
#endif
220+
205221
return mpd_send_command(connection, "seekcur", ts, NULL);
206222
}
207223

src/send.c

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,16 @@
66
#include "isend.h"
77
#include "internal.h"
88
#include "sync.h"
9+
#include "config.h" // for HAVE_USELOCALE
910

1011
#include <stdarg.h>
1112
#include <limits.h>
1213
#include <stdio.h>
1314

15+
#ifdef HAVE_USELOCALE
16+
#include <locale.h>
17+
#endif
18+
1419
/* (bits+1)/3 (plus the sign character) */
1520
enum {
1621
INTLEN = (sizeof(int) * CHAR_BIT + 1) / 3 + 1,
@@ -31,11 +36,22 @@ format_range(char *buffer, size_t size, unsigned start, unsigned end)
3136
static void
3237
format_frange(char *buffer, size_t size, float start, float end)
3338
{
39+
#ifdef HAVE_USELOCALE
40+
// use the POSIX locale to format floating point numbers
41+
const locale_t my_locale = newlocale(LC_NUMERIC_MASK, "C", NULL);
42+
const locale_t old_locale = uselocale(my_locale);
43+
#endif
44+
3445
/* the special value 0.0 means "open range" */
3546
if (end >= 0)
3647
snprintf(buffer, size, "%1.3f:%1.3f", (double)start, (double)end);
3748
else
3849
snprintf(buffer, size, "%1.3f:", (double)start);
50+
51+
#ifdef HAVE_USELOCALE
52+
uselocale(old_locale);
53+
freelocale(my_locale);
54+
#endif
3955
}
4056

4157
/**
@@ -153,9 +169,20 @@ bool
153169
mpd_send_float_command(struct mpd_connection *connection, const char *command,
154170
float arg)
155171
{
156-
char arg_string[FLOATLEN];
172+
#ifdef HAVE_USELOCALE
173+
// use the POSIX locale to format floating point numbers
174+
const locale_t my_locale = newlocale(LC_NUMERIC_MASK, "C", NULL);
175+
const locale_t old_locale = uselocale(my_locale);
176+
#endif
157177

178+
char arg_string[FLOATLEN];
158179
snprintf(arg_string, sizeof(arg_string), "%f", (double)arg);
180+
181+
#ifdef HAVE_USELOCALE
182+
uselocale(old_locale);
183+
freelocale(my_locale);
184+
#endif
185+
159186
return mpd_send_command(connection, command, arg_string, NULL);
160187
}
161188

@@ -187,10 +214,22 @@ bool
187214
mpd_send_u_f_command(struct mpd_connection *connection, const char *command,
188215
unsigned arg1, float arg2)
189216
{
217+
#ifdef HAVE_USELOCALE
218+
// use the POSIX locale to format floating point numbers
219+
const locale_t my_locale = newlocale(LC_NUMERIC_MASK, "C", NULL);
220+
const locale_t old_locale = uselocale(my_locale);
221+
#endif
222+
190223
char arg1_string[INTLEN], arg2_string[FLOATLEN];
191224

192225
snprintf(arg1_string, sizeof(arg1_string), "%u", arg1);
193226
snprintf(arg2_string, sizeof(arg2_string), "%.3f", (double)arg2);
227+
228+
#ifdef HAVE_USELOCALE
229+
uselocale(old_locale);
230+
freelocale(my_locale);
231+
#endif
232+
194233
return mpd_send_command(connection, command,
195234
arg1_string, arg2_string, NULL);
196235
}

0 commit comments

Comments
 (0)