mirror of
https://github.com/nasa/trick.git
synced 2024-12-21 06:03:10 +00:00
2a03ff5cf4
* Replace sprintf with snprintf in all of Trick source. #1384 * Don't add -Werror for MacOS because of deprecated sprintf warnings which we cant get rid of because SWIG. #1384 * Fixed an unbalanced parenthesis in S_overrides.mk. #1384
295 lines
9.5 KiB
C
295 lines
9.5 KiB
C
/*
|
|
PURPOSE: ( Functions to convert narrow (char) strings to wide (wchar_t) strings and vice-versa, as well as functions
|
|
to determine the number of characters that would result, without actually performing a conversion.)
|
|
|
|
PROGRAMMERS: (((John M. Penn) (L-3 Communications) (08/2006))) */
|
|
|
|
#if !( __Lynx__ || __sgi || __INTERIX)
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <wctype.h>
|
|
#include <limits.h>
|
|
#include "trick/wcs_ext.h"
|
|
|
|
|
|
size_t wcs_to_ncs_len(const wchar_t * wcs)
|
|
{
|
|
return wcs_to_ncs(wcs, (char *) NULL, (size_t) 0);
|
|
}
|
|
|
|
size_t ncs_to_wcs_len(const char *ncs)
|
|
{
|
|
return ncs_to_wcs(ncs, (wchar_t *) NULL, (size_t) 0);
|
|
}
|
|
|
|
size_t wcs_to_ncs(const wchar_t * wcs, char *ncs, size_t ncs_max_len)
|
|
{
|
|
unsigned int i, wlen, nlen;
|
|
|
|
if (wcs == (wchar_t *) NULL) {
|
|
fprintf(stderr, "%s:wcs_to_ncs: Wide input character string is NULL. No conversion performed.\n", __FILE__);
|
|
return 0;
|
|
}
|
|
|
|
wlen = wcslen(wcs);
|
|
nlen = 0;
|
|
if (ncs != NULL) {
|
|
ncs[0] = '\0';
|
|
}
|
|
|
|
for (i = 0; i < wlen; i++) {
|
|
wint_t wcint = wcs[i];
|
|
char work_s[11];
|
|
|
|
if (iswprint(wcint)) {
|
|
int len;
|
|
/* The wide character is printable in the current locale, so create a multibyte, external representation of
|
|
it. Note that the external representation will also be printable in the current locale. */
|
|
|
|
if (wcint == '\'') {
|
|
snprintf(work_s, sizeof(work_s), "\\\'");
|
|
} else if (wcint == '\"') {
|
|
snprintf(work_s, sizeof(work_s), "\\\"");
|
|
} else if (wcint == '\?') {
|
|
snprintf(work_s, sizeof(work_s), "\\\?");
|
|
} else if (wcint == '\\') {
|
|
snprintf(work_s, sizeof(work_s), "\\\\");
|
|
} else {
|
|
len = wcrtomb(work_s, (wchar_t) wcint, NULL);
|
|
work_s[len] = '\0';
|
|
}
|
|
|
|
} else {
|
|
/* The wide character is not printable in the current locale so, create a printable, external
|
|
representation of this non-printable character. */
|
|
if (wcint <= 0xFF) {
|
|
if (wcint == '\a') {
|
|
snprintf(work_s, sizeof(work_s), "\\a");
|
|
} else if (wcint == '\b') {
|
|
snprintf(work_s, sizeof(work_s), "\\b");
|
|
} else if (wcint == '\f') {
|
|
snprintf(work_s, sizeof(work_s), "\\f");
|
|
} else if (wcint == '\n') {
|
|
snprintf(work_s, sizeof(work_s), "\\n");
|
|
} else if (wcint == '\r') {
|
|
snprintf(work_s, sizeof(work_s), "\\n");
|
|
} else if (wcint == '\t') {
|
|
snprintf(work_s, sizeof(work_s), "\\t");
|
|
} else if (wcint == '\v') {
|
|
snprintf(work_s, sizeof(work_s), "\\v");
|
|
} else {
|
|
snprintf(work_s, sizeof(work_s), "\\x%02x", wcint);
|
|
}
|
|
} else if (wcint <= 0xFFFF) {
|
|
snprintf(work_s, sizeof(work_s), "\\u%04X", wcint);
|
|
} else {
|
|
snprintf(work_s, sizeof(work_s), "\\U%08X", wcint);
|
|
}
|
|
}
|
|
|
|
nlen += strlen(work_s);
|
|
|
|
if (ncs != NULL) {
|
|
if (nlen < ncs_max_len) {
|
|
strcat(ncs, work_s);
|
|
} else {
|
|
fprintf(stderr, "%s:wcs_to_ncs: Insufficient storage for the (narrow) output character string.\n",
|
|
__FILE__);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
} /* end-for each wide character */
|
|
|
|
return (nlen);
|
|
}
|
|
|
|
size_t ncs_to_wcs(const char *ncs, wchar_t * wcs, size_t w_max_size)
|
|
{
|
|
|
|
mbstate_t state;
|
|
wchar_t wc_in, wc_out = 0;
|
|
int code = 0;
|
|
int pstate = 0;
|
|
size_t wlen = 0;
|
|
size_t nbytes;
|
|
size_t len; /* number of bytes remaining in the input string. */
|
|
|
|
if (ncs == (char *) NULL) {
|
|
fprintf(stderr, "%s:ncs_to_wcs: Narrow input character string is NULL. No conversion performed.\n", __FILE__);
|
|
return 0;
|
|
}
|
|
len = strlen(ncs);
|
|
|
|
memset(&state, '\0', sizeof(state));
|
|
|
|
/* While we have another wide-character and there is sufficient space to store it ... The extra (len > 0 ) check is
|
|
for the Macs because mbrtowc still returns values > 0 if len == 0 */
|
|
while (((nbytes = mbrtowc(&wc_in, ncs, len, &state)) > 0) && (len > 0)) {
|
|
|
|
wint_t wcint;
|
|
int digits_remaining = 0;
|
|
int digit = 0;
|
|
|
|
len -= nbytes;
|
|
ncs += nbytes;
|
|
wcint = (wint_t) wc_in;
|
|
|
|
if (pstate && (wcint > 0x7F)) {
|
|
// We should only find ASCII characters in the escaped state.
|
|
fprintf(stderr, "%s:ncs_to_wcs: Unknown escape sequence. No conversion performed.\n", __FILE__);
|
|
return 0;
|
|
}
|
|
|
|
switch (pstate) {
|
|
case 0:{
|
|
if (wcint == '\\') {
|
|
pstate = 1;
|
|
} else {
|
|
// Store the wide-character.
|
|
wc_out = wc_in;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 1:{
|
|
switch (wcint) {
|
|
case '\'':
|
|
case '\"':
|
|
case '\?':
|
|
case '\\':{
|
|
wc_out = wc_in;
|
|
pstate = 0;
|
|
}
|
|
break;
|
|
|
|
case 'a':{
|
|
wc_out = btowc((int) '\a');
|
|
pstate = 0;
|
|
} break;
|
|
case 'b':{
|
|
wc_out = btowc((int) '\b');
|
|
pstate = 0;
|
|
} break;
|
|
case 'f':{
|
|
wc_out = btowc((int) '\f');
|
|
pstate = 0;
|
|
} break;
|
|
case 'n':{
|
|
wc_out = btowc((int) '\n');
|
|
pstate = 0;
|
|
} break;
|
|
case 'r':{
|
|
wc_out = btowc((int) '\r');
|
|
pstate = 0;
|
|
} break;
|
|
case 't':{
|
|
wc_out = btowc((int) '\t');
|
|
pstate = 0;
|
|
} break;
|
|
case 'v':{
|
|
wc_out = btowc((int) '\v');
|
|
pstate = 0;
|
|
} break;
|
|
case 'x':{
|
|
pstate = 2;
|
|
digits_remaining = 2;
|
|
code = 0;
|
|
}
|
|
break;
|
|
case 'u':{
|
|
pstate = 2;
|
|
digits_remaining = 4;
|
|
code = 0;
|
|
}
|
|
break;
|
|
case 'U':{
|
|
pstate = 2;
|
|
digits_remaining = 8;
|
|
code = 0;
|
|
}
|
|
break;
|
|
default:{
|
|
fprintf(stderr, "%s:ncs_to_wcs: Unknown escape sequence. No conversion performed.\n",
|
|
__FILE__);
|
|
return 0;
|
|
}
|
|
} // switch wcint
|
|
|
|
}
|
|
break; // case 1
|
|
|
|
case 2:{
|
|
if (digits_remaining > 0) {
|
|
if (wcint >= '0' && wcint <= '9') {
|
|
digit = (int) wcint - (int) '0';
|
|
} else if (wcint >= 'A' && wcint <= 'F') {
|
|
digit = (int) wcint - (int) 'A' + 10;;
|
|
} else if (wcint >= 'a' && wcint <= 'f') {
|
|
digit = (int) wcint - (int) 'a' + 10;;
|
|
} else {
|
|
// error
|
|
}
|
|
code = code * 16 + digit;
|
|
digits_remaining--;
|
|
|
|
if (digits_remaining == 0) {
|
|
wc_out = code;
|
|
pstate = 0;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
} /* switch */
|
|
|
|
if (pstate == 0) {
|
|
if (wcs != NULL) {
|
|
if (wlen < w_max_size) {
|
|
wcs[wlen] = wc_out;
|
|
} else {
|
|
fprintf(stderr, "%s:ncs_to_wcs: Insufficient storage for the (wide) output character string.\n",
|
|
__FILE__);
|
|
}
|
|
}
|
|
wlen++;
|
|
}
|
|
|
|
|
|
} /* while */
|
|
|
|
if (wcs == NULL) {
|
|
return wlen;
|
|
}
|
|
|
|
if (wlen < w_max_size) {
|
|
wcs[wlen] = 0 ;
|
|
return wlen;
|
|
} else {
|
|
fprintf(stderr, "%s:ncs_to_wcs: Insufficient storage for the (wide) output character string.\n", __FILE__);
|
|
return 0;
|
|
}
|
|
}
|
|
#else
|
|
int wcs_to_ncs_len(void)
|
|
{
|
|
return (0);
|
|
}
|
|
|
|
int ncs_to_wcs_len(void)
|
|
{
|
|
return (0);
|
|
}
|
|
|
|
int wcs_to_ncs(void)
|
|
{
|
|
return (0);
|
|
}
|
|
|
|
int ncs_to_wcs(void)
|
|
{
|
|
return (0);
|
|
}
|
|
#endif
|