7
7
#include < stdarg.h>
8
8
#include < limits.h>
9
9
#include < locale.h>
10
+
11
+ #if __unix__
12
+ # include < unistd.h> // For _POSIX_VERSION
13
+ #endif
14
+
10
15
#include " svm.h"
16
+
11
17
int libsvm_version = LIBSVM_VERSION;
12
18
typedef float Qfloat;
13
19
typedef signed char schar;
@@ -2638,16 +2644,55 @@ static const char *kernel_type_table[]=
2638
2644
" linear" ," polynomial" ," rbf" ," sigmoid" ," precomputed" ,NULL
2639
2645
};
2640
2646
2641
- int svm_save_model (const char *model_file_name, const svm_model *model)
2647
+ #if _POSIX_VERSION >= 200809L
2648
+
2649
+ // If possible, use the thread-safe uselocale() function
2650
+ typedef locale_t locale_handle;
2651
+
2652
+ static locale_handle set_c_locale ()
2642
2653
{
2643
- FILE *fp = fopen (model_file_name," w" );
2644
- if (fp==NULL ) return -1 ;
2654
+ locale_handle c_locale = newlocale (LC_ALL_MASK, " C" , 0 );
2655
+ locale_handle old_locale = uselocale (c_locale);
2656
+ return old_locale;
2657
+ }
2658
+
2659
+ static void restore_locale (locale_handle locale)
2660
+ {
2661
+ locale_handle c_locale = uselocale (locale);
2662
+ if (c_locale && c_locale != LC_GLOBAL_LOCALE) {
2663
+ freelocale (c_locale);
2664
+ }
2665
+ }
2666
+
2667
+ #else
2668
+
2669
+ // But fall back to setlocale() if uselocale() is not available
2670
+ typedef char *locale_handle;
2645
2671
2646
- char *old_locale = setlocale (LC_ALL, NULL );
2672
+ static locale_handle set_c_locale ()
2673
+ {
2674
+ locale_handle old_locale = setlocale (LC_ALL, NULL );
2647
2675
if (old_locale) {
2648
2676
old_locale = strdup (old_locale);
2649
2677
}
2650
2678
setlocale (LC_ALL, " C" );
2679
+ return old_locale;
2680
+ }
2681
+
2682
+ static void restore_locale (locale_handle locale)
2683
+ {
2684
+ setlocale (LC_ALL, locale);
2685
+ free (locale);
2686
+ }
2687
+
2688
+ #endif
2689
+
2690
+ int svm_save_model (const char *model_file_name, const svm_model *model)
2691
+ {
2692
+ FILE *fp = fopen (model_file_name," w" );
2693
+ if (fp==NULL ) return -1 ;
2694
+
2695
+ locale_handle old_locale = set_c_locale ();
2651
2696
2652
2697
const svm_parameter& param = model->param ;
2653
2698
@@ -2728,8 +2773,7 @@ int svm_save_model(const char *model_file_name, const svm_model *model)
2728
2773
fprintf (fp, " \n " );
2729
2774
}
2730
2775
2731
- setlocale (LC_ALL, old_locale);
2732
- free (old_locale);
2776
+ restore_locale (old_locale);
2733
2777
2734
2778
if (ferror (fp) != 0 || fclose (fp) != 0 ) return -1 ;
2735
2779
else return 0 ;
@@ -2878,11 +2922,7 @@ svm_model *svm_load_model(const char *model_file_name)
2878
2922
FILE *fp = fopen (model_file_name," rb" );
2879
2923
if (fp==NULL ) return NULL ;
2880
2924
2881
- char *old_locale = setlocale (LC_ALL, NULL );
2882
- if (old_locale) {
2883
- old_locale = strdup (old_locale);
2884
- }
2885
- setlocale (LC_ALL, " C" );
2925
+ locale_handle old_locale = set_c_locale ();
2886
2926
2887
2927
// read parameters
2888
2928
@@ -2898,8 +2938,7 @@ svm_model *svm_load_model(const char *model_file_name)
2898
2938
if (!read_model_header (fp, model))
2899
2939
{
2900
2940
fprintf (stderr, " ERROR: fscanf failed to read model\n " );
2901
- setlocale (LC_ALL, old_locale);
2902
- free (old_locale);
2941
+ restore_locale (old_locale);
2903
2942
free (model->rho );
2904
2943
free (model->label );
2905
2944
free (model->nSV );
@@ -2971,8 +3010,7 @@ svm_model *svm_load_model(const char *model_file_name)
2971
3010
}
2972
3011
free (line);
2973
3012
2974
- setlocale (LC_ALL, old_locale);
2975
- free (old_locale);
3013
+ restore_locale (old_locale);
2976
3014
2977
3015
if (ferror (fp) != 0 || fclose (fp) != 0 )
2978
3016
return NULL ;
0 commit comments