[PATCH] Parse the configuration file in C locale

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Aur?lien,

On Sun, 6 Apr 2008 22:58:39 +0200, Aurelien Jarno wrote:
> The configuration file is currently parsed in the locale set by the main
> program using the library. This means that if the decimal separator
> (defined in LC_NUMERIC) is not '.' the values in the compute lines are
> truncated. This happens for example with sensors-applet and a French
> locale.

Good catch.

> 
> The patch below is an attempt to fix that. There may be more clever ways
> to do that, but currently I fail to find them.
> 
> 
> Index: lib/init.c
> ===================================================================
> --- lib/init.c	(r?vision 5168)
> +++ lib/init.c	(copie de travail)
> @@ -19,6 +19,7 @@
>      MA 02110-1301 USA.
>  */
>  
> +#include <locale.h>
>  #include <stdlib.h>
>  #include <stdio.h>
>  #include <errno.h>
> @@ -37,6 +38,7 @@
>  int sensors_init(FILE *input)
>  {
>  	int res;
> +	char *locale = NULL;
>  
>  	if (!sensors_init_sysfs())
>  		return -SENSORS_ERR_KERNEL;
> @@ -44,6 +46,13 @@
>  	    (res = sensors_read_sysfs_chips()))
>  		goto exit_cleanup;
>  
> +	/* Read the current locale */
> +	locale = setlocale(LC_NUMERIC, NULL);
> +	if (locale)
> +		locale = strdup(locale);
> +	/* Set the locale to C */
> +	setlocale(LC_NUMERIC, "C");
> +
>  	res = -SENSORS_ERR_PARSE;
>  	if (input) {
>  		if (sensors_scanner_init(input) ||
> @@ -64,11 +73,21 @@
>  		}
>  	}
>  
> +	/* Restore the old locale */
> +	if (locale) {
> +		setlocale(LC_NUMERIC, locale);
> +		free(locale);
> +	}
>  	if ((res = sensors_substitute_busses()))
>  		goto exit_cleanup;
>  	return 0;
>  
>  exit_cleanup:
> +	/* Restore the old locale */
> +	if (locale) {
> +		setlocale(LC_NUMERIC, locale);
> +		free(locale);
> +	}
>  	sensors_cleanup();
>  	return res;
>  }
> 

I've come up with a variant where we don't need to duplicate the
clear-up step in the error path:

---
 lib/init.c |   31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

--- lib/init.c.orig	2008-04-07 21:32:53.000000000 +0200
+++ lib/init.c	2008-04-07 21:48:18.000000000 +0200
@@ -19,8 +19,10 @@
     MA 02110-1301 USA.
 */
 
+#include <locale.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <errno.h>
 #include "sensors.h"
 #include "data.h"
@@ -34,6 +36,31 @@
 #define DEFAULT_CONFIG_FILE	ETCDIR "/sensors3.conf"
 #define ALT_CONFIG_FILE		ETCDIR "/sensors.conf"
 
+/* Wrapper around sensors_yyparse(), which clears the locale so that
+   the decimal numbers are always parsed properly. */
+static int sensors_parse(void)
+{
+	int res;
+	char *locale;
+
+	/* Remember the current locale and clear it */
+	locale = setlocale(LC_ALL, NULL);
+	if (locale) {
+		locale = strdup(locale);
+		setlocale(LC_ALL, "C");
+	}
+
+	res = sensors_yyparse();
+
+	/* Restore the old locale */
+	if (locale) {
+		setlocale(LC_ALL, locale);
+		free(locale);
+	}
+
+	return res;
+}
+
 int sensors_init(FILE *input)
 {
 	int res;
@@ -47,7 +74,7 @@ int sensors_init(FILE *input)
 	res = -SENSORS_ERR_PARSE;
 	if (input) {
 		if (sensors_scanner_init(input) ||
-		    sensors_yyparse())
+		    sensors_parse())
 			goto exit_cleanup;
 	} else {
 		/* No configuration provided, use default */
@@ -56,7 +83,7 @@ int sensors_init(FILE *input)
 			input = fopen(ALT_CONFIG_FILE, "r");
 		if (input) {
 			if (sensors_scanner_init(input) ||
-			    sensors_yyparse()) {
+			    sensors_parse()) {
 				fclose(input);
 				goto exit_cleanup;
 			}

I've also changed LC_NUMERIC for LC_ALL, as discussed on IRC. Otherwise
it's the same as your original patch.

I'll apply this patch tomorrow if nobody objects.

Thanks,
-- 
Jean Delvare




[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux