Added UTF8 multibyte to wide char printing in some apps (#106)

* Added UTF8 multibyte to wide char printing in some apps

* Fix test compile

* Reduce diff churn

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2020-07-27 22:44:43 -05:00
committed by GitHub
parent 2af16ab14d
commit f41b5377cc
5 changed files with 111 additions and 12 deletions
+14
View File
@@ -31,6 +31,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* for time */
#ifdef __STDC_ISO_10646__
#include <locale.h>
#endif
#include <errno.h>
#include <assert.h>
#include "bacnet/config.h"
@@ -1438,6 +1441,17 @@ int main(int argc, char *argv[])
address_init();
Init_Service_Handlers();
dlenv_init();
#ifdef __STDC_ISO_10646__
/* Internationalized programs must call setlocale()
* to initiate a specific language operation.
* This can be done by calling setlocale() as follows.
* If your native locale doesn't use UTF-8 encoding
* you need to replace the empty string with a
* locale like "en_US.utf8" which is the same as the string
* used in the enviromental variable "LANG=en_US.UTF-8".
*/
setlocale(LC_ALL, "");
#endif
atexit(datalink_cleanup);
/* configure the timeout values */
+14
View File
@@ -29,6 +29,9 @@
#include <stdlib.h>
#include <errno.h>
#include <time.h> /* for time */
#ifdef __STDC_ISO_10646__
#include <locale.h>
#endif
#define PRINT_ENABLED 1
@@ -363,6 +366,17 @@ int main(int argc, char *argv[])
Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE);
Init_Service_Handlers();
dlenv_init();
#ifdef __STDC_ISO_10646__
/* Internationalized programs must call setlocale()
* to initiate a specific language operation.
* This can be done by calling setlocale() as follows.
* If your native locale doesn't use UTF-8 encoding
* you need to replace the empty string with a
* locale like "en_US.utf8" which is the same as the string
* used in the enviromental variable "LANG=en_US.UTF-8".
*/
setlocale(LC_ALL, "");
#endif
atexit(datalink_cleanup);
/* configure the timeout values */
last_seconds = time(NULL);
+14
View File
@@ -29,6 +29,9 @@
#include <stdlib.h>
#include <errno.h>
#include <time.h> /* for time */
#ifdef __STDC_ISO_10646__
#include <locale.h>
#endif
#define PRINT_ENABLED 1
@@ -423,6 +426,17 @@ int main(int argc, char *argv[])
address_init();
Init_Service_Handlers();
dlenv_init();
#ifdef __STDC_ISO_10646__
/* Internationalized programs must call setlocale()
* to initiate a specific language operation.
* This can be done by calling setlocale() as follows.
* If your native locale doesn't use UTF-8 encoding
* you need to replace the empty string with a
* locale like "en_US.utf8" which is the same as the string
* used in the enviromental variable "LANG=en_US.UTF-8".
*/
setlocale(LC_ALL, "");
#endif
atexit(datalink_cleanup);
/* configure the timeout values */
last_seconds = time(NULL);
+14
View File
@@ -31,6 +31,9 @@
#include <stdlib.h>
#include <errno.h>
#include <time.h> /* for time */
#ifdef __STDC_ISO_10646__
#include <locale.h>
#endif
#include "bacnet/bacdef.h"
#include "bacnet/config.h"
#include "bacnet/bactext.h"
@@ -320,6 +323,17 @@ int main(int argc, char *argv[])
address_init();
Init_Service_Handlers();
dlenv_init();
#ifdef __STDC_ISO_10646__
/* Internationalized programs must call setlocale()
* to initiate a specific language operation.
* This can be done by calling setlocale() as follows.
* If your native locale doesn't use UTF-8 encoding
* you need to replace the empty string with a
* locale like "en_US.utf8" which is the same as the string
* used in the enviromental variable "LANG=en_US.UTF-8".
*/
setlocale(LC_ALL, "");
#endif
atexit(datalink_cleanup);
/* configure the timeout values */
last_seconds = time(NULL);
+55 -12
View File
@@ -35,8 +35,12 @@
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdlib.h> /* for strtol */
#include <ctype.h> /* for isalnum */
#ifdef __STDC_ISO_10646__
#include <wchar.h>
#include <wctype.h>
#endif
#include "bacnet/bacenum.h"
#include "bacnet/bacdcode.h"
#include "bacnet/bacint.h"
@@ -1038,6 +1042,12 @@ int bacapp_snprintf_value(
char *p_str = str;
size_t rem_str_len = str_len;
char temp_str[32];
#ifdef __STDC_ISO_10646__
/* Wide character (decoded from multi-byte character). */
wchar_t wc;
/* Wide character length in bytes. */
int wclen;
#endif
if (object_value && object_value->value) {
value = object_value->value;
@@ -1102,17 +1112,50 @@ int bacapp_snprintf_value(
char_str = characterstring_value(&value->type.Character_String);
if (!append_str(&p_str, &rem_str_len, "\"")) {
break;
}
for (i = 0; i < len; i++) {
if (isprint(*((unsigned char *)char_str))) {
snprintf(temp_str, sizeof(temp_str), "%c", *char_str);
} else {
snprintf(temp_str, sizeof(temp_str), "%c", '.');
}
#ifdef __STDC_ISO_10646__
if (characterstring_encoding(&value->type.Character_String) ==
CHARACTER_UTF8) {
while (len > 0) {
wclen = mbtowc(&wc, char_str, MB_CUR_MAX);
if (wclen == -1) {
/* Encoding error, reset state: */
mbtowc(NULL, NULL, MB_CUR_MAX);
/* After handling an invalid byte,
retry with the next one. */
wclen = 1;
wc = L'?';
} else {
if (!iswprint(wc)) {
wc = L'.';
}
}
snprintf(temp_str, sizeof(temp_str), "%lc", wc);
if (!append_str(&p_str, &rem_str_len, temp_str)) {
break;
}
if (len > wclen) {
len -= wclen;
char_str += wclen;
} else {
len = 0;
}
}
} else
#endif
{
for (i = 0; i < len; i++) {
if (isprint(*((unsigned char *)char_str))) {
snprintf(temp_str, sizeof(temp_str), "%c",
*char_str);
} else {
snprintf(temp_str, sizeof(temp_str), "%c", '.');
}
if (!append_str(&p_str, &rem_str_len, temp_str)) {
break;
}
char_str++;
}
if (!append_str(&p_str, &rem_str_len, temp_str)) {
break;
}
char_str++;
}
if ((i == len) && append_str(&p_str, &rem_str_len, "\"")) {
/* Everything is fine. Indicate how many bytes were */