Skip to content

Commit

Permalink
Fix MacOS std::setlocale writing errno
Browse files Browse the repository at this point in the history
In MacOS std::setlocale writes errno. This provokes erroneus error
messages in the Khiops logs. To fix it this patch implements a a
portability wrapper p_SetLocale.
  • Loading branch information
folmos-at-orange committed Jan 15, 2024
1 parent a767b14 commit 6aea4e2
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 12 deletions.
22 changes: 20 additions & 2 deletions src/Norm/base/Portability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,32 @@
// Declaration de la methode de Standard.h permettant d'acceder aux buffers de travail
extern char* StandardGetBuffer();

// MacOS note: The MacOS libc implementation of setlocale sets errno to zero (it shouldn't from the
// spec). So, in MacOS we save the state of `errno` and restore it after the call to setlocale.
char* p_SetLocale(int category, const char* locale)
{
char* currentLocale;
#ifdef __APPLE__
int currentErrno;

currentErrno = errno;
#endif
currentLocale = setlocale(category, locale);
#ifdef __APPLE__
errno = currentErrno;
#endif

return currentLocale;
}

void p_SetMachineLocale()
{
setlocale(LC_ALL, "");
p_SetLocale(LC_ALL, "");
}

void p_SetApplicationLocale()
{
setlocale(LC_ALL, "en_US.UTF-8");
p_SetLocale(LC_ALL, "en_US.UTF-8");
}

/////////////////////////////////////////////////////////////////
Expand Down
14 changes: 9 additions & 5 deletions src/Norm/base/Portability.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,16 @@ char* p_strcpy(char* strDestination, const char* strSource);
char* p_strncpy(char* strDest, const char* strSource, size_t count);
char* p_strcat(char* strDestination, const char* strSource);

// Le locale de l'application est parametre de facon a etre independant de la machine,
// pour assurer l'unicite des conversions numeriques et de leur format d'export, des tris,
// et des comparaisons entre chaines de caracteres
// Portable wrapper of std::setlocale to avoid errno side effets in MacOS
// See the implementation for details.
char* p_SetLocale(int category, const char* locale);

// Le locale de l'application est parametre de facon a etre independant de la machine, pour assurer
// l'unicite des conversions numeriques et de leur format d'export, des tris, et des comparaisons
// entre chaines de caracteres
//
// Parametrage des locales: toute fonction de FileService base sur un nom de fichier entoure son appel
// d'un parametrage prealable au locale de la machine, puis restore le locale de l'application
// Parametrage des locales: toute fonction de FileService base sur un nom de fichier entoure son
// appel d'un parametrage prealable au locale de la machine, puis restore le locale de l'application
// Dans le cas d'un besoin de parametrage de locale specifique, il est necessaire de repositionner
// ensuite le locale par defaut par appel a p_SetApplicationLocale.
void p_SetMachineLocale();
Expand Down
10 changes: 5 additions & 5 deletions src/Norm/base/UIObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1203,7 +1203,7 @@ JNIEnv* UIObject::GraphicGetJNIEnv()
bGraphicIsLoaded = true;

// Memorisation du locale courant (modifie par Java)
sCurrentLocale = setlocale(LC_ALL, NULL);
sCurrentLocale = p_SetLocale(LC_ALL, NULL);

// Recherche de la classe JFrame pour savoir si on a acces au GUI
cls = env->FindClass("javax/swing/JFrame");
Expand Down Expand Up @@ -1564,7 +1564,7 @@ const ALString UIObject::NativeFromJstring(JNIEnv* envValue, const jstring value
jbyte* p_bytes;

// Memorisation du locale courant (modifie par Java: cf GraphicGetJNIEnv)
sCurrentLocale = setlocale(LC_ALL, NULL);
sCurrentLocale = p_SetLocale(LC_ALL, NULL);

// On utilise directment l'API JNI (sans passer par GraphicGetClassID ou GraphicGetMethodID)
// pour eviter les recursion avec GraphicGetJNIEnv
Expand Down Expand Up @@ -1595,7 +1595,7 @@ const ALString UIObject::NativeFromJstring(JNIEnv* envValue, const jstring value
envValue->ReleaseByteArrayElements(byte_array, p_bytes, 0);

// Restitution du locale courant
setlocale(LC_ALL, sCurrentLocale);
p_SetLocale(LC_ALL, sCurrentLocale);
return sResult;
}

Expand All @@ -1612,7 +1612,7 @@ const jstring UIObject::NativeToJstring(JNIEnv* envValue, const ALString& sValue
require(envValue != NULL);

// Memorisation du locale courant (modifie par Java: cf GraphicGetJNIEnv)
sCurrentLocale = setlocale(LC_ALL, NULL);
sCurrentLocale = p_SetLocale(LC_ALL, NULL);

// On utilise directment l'API JNI (sans passer par GraphicGetClassID ou GraphicGetMethodID)
// pour eviter les recursion avec GraphicGetJNIEnv
Expand All @@ -1637,7 +1637,7 @@ const jstring UIObject::NativeToJstring(JNIEnv* envValue, const ALString& sValue
jstringValue = (jstring)envValue->NewObject(class_java_lang_String, mid_string_ctor, byte_array, codeString);

// Restitution du locale courant
setlocale(LC_ALL, sCurrentLocale);
p_SetLocale(LC_ALL, sCurrentLocale);
return jstringValue;
}

Expand Down

0 comments on commit 6aea4e2

Please sign in to comment.