213 lines
5.1 KiB
C
213 lines
5.1 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2001, 2007 Fidelity Information Services, Inc *
|
||
|
* *
|
||
|
* This source code contains the intellectual property *
|
||
|
* of its copyright holder(s), and is made available *
|
||
|
* under a license. If you do not know the terms of *
|
||
|
* the license, please stop and do not read further. *
|
||
|
* *
|
||
|
****************************************************************/
|
||
|
#include "mdef.h"
|
||
|
|
||
|
#include "gtm_string.h"
|
||
|
|
||
|
#include "mlkdef.h"
|
||
|
#include "zshow.h"
|
||
|
#include "patcode.h"
|
||
|
#include "compiler.h" /* for CHARMAXARGS */
|
||
|
|
||
|
#ifdef UNICODE_SUPPORTED
|
||
|
#include "gtm_icu_api.h" /* U_ISPRINT() needs this header */
|
||
|
#include "gtm_utf8.h"
|
||
|
#endif
|
||
|
|
||
|
GBLREF uint4 *pattern_typemask;
|
||
|
GBLREF boolean_t gtm_utf8_mode;
|
||
|
|
||
|
/* Routine to convert a string to ZWRITE format. Used by the utiltities.
|
||
|
* NOTE: this routine does almost the same formatting as mval_write(). The reason
|
||
|
* for not using mval_write() is because it is much more complex than we need
|
||
|
* here. Moreover, this version is more efficient due to the availability of
|
||
|
* pre-allocated destination buffer */
|
||
|
int format2zwr(sm_uc_ptr_t src, int src_len, unsigned char *des, int *des_len)
|
||
|
{
|
||
|
sm_uc_ptr_t cp;
|
||
|
uint4 ch;
|
||
|
int fastate = 0, ncommas, dstlen, chlen;
|
||
|
boolean_t isctl, isill;
|
||
|
uchar_ptr_t srctop, strnext, tmpptr;
|
||
|
|
||
|
dstlen = *des_len = 0;
|
||
|
|
||
|
if (src_len > 0)
|
||
|
{
|
||
|
srctop = src + src_len;
|
||
|
fastate = 0;
|
||
|
/* deals with the other characters */
|
||
|
for (cp = src; cp < srctop; cp += chlen)
|
||
|
{
|
||
|
if (!gtm_utf8_mode)
|
||
|
{
|
||
|
ch = *cp;
|
||
|
isctl = ((pattern_typemask[ch] & PATM_C) != 0);
|
||
|
isill = FALSE;
|
||
|
chlen = 1;
|
||
|
}
|
||
|
#ifdef UNICODE_SUPPORTED
|
||
|
else {
|
||
|
strnext = UTF8_MBTOWC(cp, srctop, ch);
|
||
|
isill = (WEOF == ch) ? (ch = *cp, TRUE) : FALSE;
|
||
|
if (!isill)
|
||
|
isctl = !U_ISPRINT(ch);
|
||
|
chlen = (int)(strnext - cp);
|
||
|
}
|
||
|
#endif
|
||
|
switch(fastate)
|
||
|
{
|
||
|
case 0: /* beginning of the string */
|
||
|
case 1: /* beginning of a new substring followed by a graphic character */
|
||
|
if (isill)
|
||
|
{
|
||
|
if (dstlen > 0)
|
||
|
{
|
||
|
des[dstlen++] = '"';
|
||
|
des[dstlen++] = '_';
|
||
|
}
|
||
|
MEMCPY_LIT(des + dstlen, DOLLARZCH);
|
||
|
dstlen += STR_LIT_LEN(DOLLARZCH);
|
||
|
I2A(des, dstlen, ch);
|
||
|
fastate = 3;
|
||
|
ncommas = 0;
|
||
|
} else if (isctl)
|
||
|
{
|
||
|
if (dstlen > 0)
|
||
|
{ /* close previous string with quote and prepare for concatenation */
|
||
|
des[dstlen++] = '"';
|
||
|
des[dstlen++] = '_';
|
||
|
}
|
||
|
MEMCPY_LIT(des + dstlen, DOLLARCH);
|
||
|
dstlen += STR_LIT_LEN(DOLLARCH);
|
||
|
I2A(des, dstlen, ch);
|
||
|
fastate = 2;
|
||
|
ncommas = 0;
|
||
|
} else
|
||
|
{ /* graphic characters */
|
||
|
if (0 == fastate) /* the initial quote in the beginning */
|
||
|
{
|
||
|
des[dstlen++] = '"';
|
||
|
fastate = 1;
|
||
|
}
|
||
|
if ('"' == ch)
|
||
|
des[dstlen++] = '"';
|
||
|
if (!gtm_utf8_mode)
|
||
|
des[dstlen++] = ch;
|
||
|
else {
|
||
|
memcpy(&des[dstlen], cp, chlen);
|
||
|
dstlen += chlen;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 2: /* subsequent characters following a non-graphic character in the
|
||
|
form of $CHAR(x,) */
|
||
|
if (isill)
|
||
|
{
|
||
|
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_DOLLARZCH);
|
||
|
dstlen += STR_LIT_LEN(CLOSE_PAREN_DOLLARZCH);
|
||
|
I2A(des, dstlen, ch);
|
||
|
fastate = 3;
|
||
|
} else if(isctl)
|
||
|
{
|
||
|
ncommas++;
|
||
|
if (CHARMAXARGS == ncommas)
|
||
|
{
|
||
|
ncommas = 0;
|
||
|
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_DOLLARCH);
|
||
|
dstlen += STR_LIT_LEN(CLOSE_PAREN_DOLLARCH);
|
||
|
} else
|
||
|
{
|
||
|
MEMCPY_LIT(des + dstlen, COMMA);
|
||
|
dstlen += STR_LIT_LEN(COMMA);
|
||
|
}
|
||
|
I2A(des, dstlen, ch);
|
||
|
} else
|
||
|
{
|
||
|
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_QUOTE);
|
||
|
dstlen += STR_LIT_LEN(CLOSE_PAREN_QUOTE);
|
||
|
if (!gtm_utf8_mode)
|
||
|
des[dstlen++] = ch;
|
||
|
else {
|
||
|
memcpy(&des[dstlen], cp, chlen);
|
||
|
dstlen += chlen;
|
||
|
}
|
||
|
if ('"' == ch)
|
||
|
des[dstlen++] = '"';
|
||
|
fastate = 1;
|
||
|
}
|
||
|
break;
|
||
|
case 3: /* subsequent characters following an illegal character in the form of $ZCHAR(x,) */
|
||
|
if(isill)
|
||
|
{
|
||
|
ncommas++;
|
||
|
if (CHARMAXARGS == ncommas)
|
||
|
{
|
||
|
ncommas = 0;
|
||
|
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_DOLLARZCH);
|
||
|
dstlen += STR_LIT_LEN(CLOSE_PAREN_DOLLARZCH);
|
||
|
} else
|
||
|
{
|
||
|
MEMCPY_LIT(des + dstlen, COMMA);
|
||
|
++dstlen;
|
||
|
}
|
||
|
I2A(des, dstlen, ch);
|
||
|
} else if (isctl)
|
||
|
{
|
||
|
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_DOLLARCH);
|
||
|
dstlen += STR_LIT_LEN(CLOSE_PAREN_DOLLARCH);
|
||
|
I2A(des, dstlen, ch);
|
||
|
fastate = 2;
|
||
|
} else
|
||
|
{
|
||
|
MEMCPY_LIT(des + dstlen, CLOSE_PAREN_QUOTE);
|
||
|
dstlen += STR_LIT_LEN(CLOSE_PAREN_QUOTE);
|
||
|
if (!gtm_utf8_mode)
|
||
|
des[dstlen++] = ch;
|
||
|
else {
|
||
|
memcpy(&des[dstlen], cp, chlen);
|
||
|
dstlen += chlen;
|
||
|
}
|
||
|
if ('"' == ch)
|
||
|
des[dstlen++] = '"';
|
||
|
fastate = 1;
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
assert(FALSE);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* close up */
|
||
|
switch(fastate)
|
||
|
{
|
||
|
case 1:
|
||
|
des[dstlen++] = '"';
|
||
|
break;
|
||
|
case 2:
|
||
|
case 3:
|
||
|
des[dstlen++] = ')';
|
||
|
break;
|
||
|
default:
|
||
|
assert(FALSE);
|
||
|
break;
|
||
|
}
|
||
|
} else
|
||
|
{
|
||
|
des[0] = des[1] = '"';
|
||
|
dstlen = 2;
|
||
|
}
|
||
|
*des_len = dstlen;
|
||
|
return 0;
|
||
|
}
|
||
|
|