aboutsummaryrefslogtreecommitdiff
path: root/libXmu/src/Xct.c
diff options
context:
space:
mode:
Diffstat (limited to 'libXmu/src/Xct.c')
-rw-r--r--libXmu/src/Xct.c1371
1 files changed, 684 insertions, 687 deletions
diff --git a/libXmu/src/Xct.c b/libXmu/src/Xct.c
index b186d27d7..258554c3a 100644
--- a/libXmu/src/Xct.c
+++ b/libXmu/src/Xct.c
@@ -1,687 +1,684 @@
-/* $Xorg: Xct.c,v 1.4 2001/02/09 02:03:53 xorgcvs Exp $ */
-
-/*
-
-Copyright 1989, 1998 The Open Group
-
-Permission to use, copy, modify, distribute, and sell this software and its
-documentation for any purpose is hereby granted without fee, provided that
-the above copyright notice appear in all copies and that both that
-copyright notice and this permission notice appear in supporting
-documentation.
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of The Open Group shall not be
-used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization from The Open Group.
-
-*/
-/* $XFree86: xc/lib/Xmu/Xct.c,v 1.8 2001/07/25 15:04:50 dawes Exp $ */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <X11/Xfuncs.h>
-#include "Xct.h"
-#include <stdio.h>
-
-#define UsedGraphic 0x0001
-#define UsedDirection 0x0002
-
-typedef struct _XctPriv {
- XctString ptr;
- XctString ptrend;
- unsigned flags;
- XctHDirection *dirstack;
- unsigned dirsize;
- char **encodings;
- unsigned enc_count;
- XctString itembuf;
- unsigned buf_count;
-} *XctPriv;
-
-#define IsMore(priv) ((priv)->ptr != (priv)->ptrend)
-#define AmountLeft(priv) ((priv)->ptrend - (priv)->ptr)
-
-#include <stdlib.h>
-
-#define HT 0x09
-#define NL 0x0a
-#define ESC 0x1b
-#define CSI 0x9b
-
-#define IsLegalC0(data, c) (((c) == HT) || ((c) == NL) || \
- (((data)->version > XctVersion) && \
- ((data)->flags & XctAcceptC0Extensions)))
-
-#define IsLegalC1(priv, c) (((data)->version > XctVersion) && \
- ((data)->flags & XctAcceptC1Extensions))
-
-#define IsI2(c) (((c) >= 0x20) && ((c) <= 0x2f))
-#define IsI3(c) (((c) >= 0x30) && ((c) <= 0x3f))
-#define IsESCF(c) (((c) >= 0x30) && ((c) <= 0x7e))
-#define IsCSIF(c) (((c) >= 0x40) && ((c) <= 0x7e))
-#define IsC0(c) ((c) <= 0x1f)
-#define IsGL(c) (((c) >= 0x20) && ((c) <= 0x7f))
-#define IsC1(c) (((c) >= 0x80) && ((c) <= 0x9f))
-#define IsGR(c) ((c) >= 0xa0)
-
-#define HasC 1
-#define HasGL 2
-#define HasGR 4
-#define ToGL 8
-
-/*
- * Prototypes
- */
-static void ComputeGLGR(XctData);
-static int Handle94GR(XctData, int);
-static int Handle96GR(XctData, int);
-static int HandleExtended(XctData data, int);
-static int HandleGL(XctData, int);
-static int HandleMultiGL(XctData, int);
-static int HandleMultiGR(XctData data, int);
-static void ShiftGRToGL(XctData, int);
-
-/*
- * Implementation
- */
-static void
-ComputeGLGR(register XctData data)
-{
- /* XXX this will need more work if more sets are registered */
- if ((data->GL_set_size == 94) && (data->GL_char_size == 1) &&
- (data->GL[0] == '\102') &&
- (data->GR_set_size == 96) && (data->GR_char_size == 1))
- data->GLGR_encoding = data->GR_encoding;
- else if ((data->GL_set_size == 94) && (data->GL_char_size == 1) &&
- (data->GL[0] == '\112') &&
- (data->GR_set_size == 94) && (data->GR_char_size == 1))
- data->GLGR_encoding = data->GR_encoding;
- else
- data->GLGR_encoding = (char *)NULL;
-}
-
-static int
-HandleGL(register XctData data, int c)
-{
- switch (c) {
- case 0x42:
- data->GL = "\102";
- data->GL_encoding = "ISO8859-1";
- break;
- case 0x4a:
- data->GL = "\112";
- data->GL_encoding = "JISX0201.1976-0";
- break;
- default:
- return 0;
- }
- data->GL_set_size = 94;
- data->GL_char_size = 1;
- ComputeGLGR(data);
- return 1;
-}
-
-static int
-HandleMultiGL(register XctData data, int c)
-{
- switch (c) {
- case 0x41:
- data->GL = "\101";
- data->GL_encoding = "GB2312.1980-0";
- break;
- case 0x42:
- data->GL = "\102";
- data->GL_encoding = "JISX0208.1983-0";
- break;
- case 0x43:
- data->GL = "\103";
- data->GL_encoding = "KSC5601.1987-0";
- break;
- default:
- return 0;
- }
- data->GL_set_size = 94;
- data->GL_char_size = 2;
-#ifdef notdef
- if (c < 0x60)
- data->GL_char_size = 2;
- else if (c < 0x70)
- data->GL_char_size = 3;
- else
- data->GL_char_size = 4;
-#endif
- data->GLGR_encoding = (char *)NULL;
- return 1;
-}
-
-static int
-Handle94GR(register XctData data, int c)
-{
- switch (c) {
- case 0x49:
- data->GR = "\111";
- data->GR_encoding = "JISX0201.1976-0";
- break;
- default:
- return 0;
- }
- data->priv->flags &= ~ToGL;
- data->GR_set_size = 94;
- data->GR_char_size = 1;
- data->GLGR_encoding = (char *)NULL;
- return 1;
-}
-
-static int
-Handle96GR(register XctData data, int c)
-{
- switch (c) {
- case 0x41:
- data->GR = "\101";
- data->GR_encoding = "ISO8859-1";
- break;
- case 0x42:
- data->GR = "\102";
- data->GR_encoding = "ISO8859-2";
- break;
- case 0x43:
- data->GR = "\103";
- data->GR_encoding = "ISO8859-3";
- break;
- case 0x44:
- data->GR = "\104";
- data->GR_encoding = "ISO8859-4";
- break;
- case 0x46:
- data->GR = "\106";
- data->GR_encoding = "ISO8859-7";
- break;
- case 0x47:
- data->GR = "\107";
- data->GR_encoding = "ISO8859-6";
- break;
- case 0x48:
- data->GR = "\110";
- data->GR_encoding = "ISO8859-8";
- break;
- case 0x4c:
- data->GR = "\114";
- data->GR_encoding = "ISO8859-5";
- break;
- case 0x4d:
- data->GR = "\115";
- data->GR_encoding = "ISO8859-9";
- break;
- default:
- return 0;
- }
- data->priv->flags &= ~ToGL;
- data->GR_set_size = 96;
- data->GR_char_size = 1;
- ComputeGLGR(data);
- return 1;
-}
-
-static int
-HandleMultiGR(register XctData data, int c)
-{
- switch (c) {
- case 0x41:
- data->GR = "\101";
- if (data->flags & XctShiftMultiGRToGL)
- data->GR_encoding = "GB2312.1980-0";
- else
- data->GR_encoding = "GB2312.1980-1";
- break;
- case 0x42:
- data->GR = "\102";
- if (data->flags & XctShiftMultiGRToGL)
- data->GR_encoding = "JISX0208.1983-0";
- else
- data->GR_encoding = "JISX0208.1983-1";
- break;
- case 0x43:
- data->GR = "\103";
- if (data->flags & XctShiftMultiGRToGL)
- data->GR_encoding = "KSC5601.1987-0";
- else
- data->GR_encoding = "KSC5601.1987-1";
- break;
- default:
- return 0;
- }
- if (data->flags & XctShiftMultiGRToGL)
- data->priv->flags |= ToGL;
- else
- data->priv->flags &= ~ToGL;
- data->GR_set_size = 94;
- data->GR_char_size = 2;
-#ifdef notdef
- if (c < 0x60)
- data->GR_char_size = 2;
- else if (c < 0x70)
- data->GR_char_size = 3;
- else
- data->GR_char_size = 4;
-#endif
- data->GLGR_encoding = (char *)NULL;
- return 1;
-}
-
-static int
-HandleExtended(register XctData data, int c)
-{
- register XctPriv priv = data->priv;
- XctString enc = data->item + 6;
- register XctString ptr = enc;
- unsigned i, len;
-
- while (*ptr != 0x02) {
- if (!*ptr || (++ptr == priv->ptr))
- return 0;
- }
- data->item = ptr + 1;
- data->item_length = priv->ptr - data->item;
- len = ptr - enc;
- for (i = 0;
- (i < priv->enc_count) &&
- strncmp(priv->encodings[i], (char *)enc, len);
- i++)
- ;
- if (i == priv->enc_count) {
- XctString cp;
-
- for (cp = enc; cp != ptr; cp++) {
- if ((!IsGL(*cp) && !IsGR(*cp)) || (*cp == 0x2a) || (*cp == 0x3f))
- return 0;
- }
- ptr = (XctString)malloc((unsigned)len + 1);
- (void) memmove((char *)ptr, (char *)enc, len);
- ptr[len] = 0x00;
- priv->enc_count++;
- if (priv->encodings)
- priv->encodings = (char **)realloc(
- (char *)priv->encodings,
- priv->enc_count * sizeof(char *));
- else
- priv->encodings = (char **)malloc(sizeof(char *));
- priv->encodings[i] = (char *)ptr;
- }
- data->encoding = priv->encodings[i];
- data->char_size = c - 0x30;
- return 1;
-}
-
-static void
-ShiftGRToGL(register XctData data, int hasCdata)
-{
- register XctPriv priv = data->priv;
- register int i;
-
- if (data->item_length > priv->buf_count) {
- priv->buf_count = data->item_length;
- if (priv->itembuf)
- priv->itembuf = (XctString)realloc((char *)priv->itembuf,
- priv->buf_count);
- else
- priv->itembuf = (XctString)malloc(priv->buf_count);
- }
- (void) memmove((char *)priv->itembuf, (char *)data->item,
- data->item_length);
- data->item = priv->itembuf;
- if (hasCdata) {
- for (i = data->item_length; --i >= 0; ) {
- if (IsGR(data->item[i]))
- data->item[i] &= 0x7f;
- }
- } else {
- for (i = data->item_length; --i >= 0; )
- data->item[i] &= 0x7f;
- }
-}
-
-/* Create an XctData structure for parsing a Compound Text string. */
-XctData
-XctCreate(_Xconst unsigned char *string, int length, XctFlags flags)
-{
- register XctData data;
- register XctPriv priv;
-
- data = (XctData)malloc(sizeof(struct _XctRec) + sizeof(struct _XctPriv));
- if (!data)
- return data;
- data->priv = priv = (XctPriv)(data + 1);
- data->total_string = (XctString)string;
- data->total_length = length;
- data->flags = flags;
- priv->dirstack = (XctHDirection *)NULL;
- priv->dirsize = 0;
- priv->encodings = (char **)NULL;
- priv->enc_count = 0;
- priv->itembuf = (XctString)NULL;
- priv->buf_count = 0;
- XctReset(data);
- return data;
-}
-
-/* Reset the XctData structure to re-parse the string from the beginning. */
-void
-XctReset(register XctData data)
-{
- register XctPriv priv = data->priv;
-
- priv->ptr = data->total_string;
- priv->ptrend = data->total_string + data->total_length;
- data->item = (XctString)NULL;
- data->item_length = 0;
- data->encoding = (char *)NULL;
- data->char_size = 1;
- data->horizontal = XctUnspecified;
- data->horz_depth = 0;
- priv->flags = 0;
- data->GL_set_size = data->GR_set_size = 0; /* XXX */
- (void)HandleGL(data, (unsigned char)0x42);
- (void)Handle96GR(data, (unsigned char)0x41);
- data->version = 1;
- data->can_ignore_exts = 0;
- /* parse version, if present */
- if ((data->total_length >= 4) &&
- (priv->ptr[0] == ESC) && (priv->ptr[1] == 0x23) &&
- IsI2(priv->ptr[2]) &&
- ((priv->ptr[3] == 0x30) || (priv->ptr[3] == 0x31))) {
- data->version = priv->ptr[2] - 0x1f;
- if (priv->ptr[3] == 0x30)
- data->can_ignore_exts = 1;
- priv->ptr += 4;
- }
-}
-
-/* Parse the next "item" from the Compound Text string. The return value
- * indicates what kind of item is returned. The item itself, and the current
- * contextual state, are reported as components of the XctData structure.
- */
-XctResult
-XctNextItem(register XctData data)
-{
- register XctPriv priv = data->priv;
- unsigned char c;
- int len, bits;
-
-#define NEXT data->item_length++; priv->ptr++
-
- while (IsMore(priv)) {
- data->item = priv->ptr;
- data->item_length = 0;
- c = *priv->ptr;
- if (c == ESC) {
- NEXT;
- while (IsMore(priv) && IsI2(*priv->ptr)) {
- NEXT;
- }
- if (!IsMore(priv))
- return XctError;
- c = *priv->ptr;
- NEXT;
- if (!IsESCF(c))
- return XctError;
- switch (data->item[1]) {
- case 0x24:
- if (data->item_length > 3) {
- if (data->item[2] == 0x28) {
- if (HandleMultiGL(data, c))
- continue;
- } else if (data->item[2] == 0x29) {
- if (HandleMultiGR(data, c))
- continue;
- }
- }
- break;
- case 0x25:
- if ((data->item_length == 4) && (data->item[2] == 0x2f) &&
- (c <= 0x3f)) {
- if ((AmountLeft(priv) < 2) ||
- (priv->ptr[0] < 0x80) || (priv->ptr[1] < 0x80))
- return XctError;
- len = *priv->ptr - 0x80;
- NEXT;
- len = (len << 7) + (*priv->ptr - 0x80);
- NEXT;
- if (AmountLeft(priv) < len)
- return XctError;
- data->item_length += len;
- priv->ptr += len;
- if (c <= 0x34) {
- if (!HandleExtended(data, c) ||
- ((data->horz_depth == 0) &&
- (priv->flags & UsedDirection)))
- return XctError;
- priv->flags |= UsedGraphic;
- return XctExtendedSegment;
- }
- }
- break;
- case 0x28:
- if (HandleGL(data, c))
- continue;
- break;
- case 0x29:
- if (Handle94GR(data, c))
- continue;
- break;
- case 0x2d:
- if (Handle96GR(data, c))
- continue;
- break;
- }
- } else if (c == CSI) {
- NEXT;
- while (IsMore(priv) && IsI3(*priv->ptr)) {
- NEXT;
- }
- while (IsMore(priv) && IsI2(*priv->ptr)) {
- NEXT;
- }
- if (!IsMore(priv))
- return XctError;
- c = *priv->ptr;
- NEXT;
- if (!IsCSIF(c))
- return XctError;
- if (c == 0x5d) {
- if ((data->item_length == 3) &&
- ((data->item[1] == 0x31) || (data->item[1] == 0x32))) {
- data->horz_depth++;
- if (priv->dirsize < data->horz_depth) {
- priv->dirsize += 10;
- if (priv->dirstack)
- priv->dirstack = (XctHDirection *)
- realloc((char *)priv->dirstack,
- priv->dirsize *
- sizeof(XctHDirection));
- else
- priv->dirstack = (XctHDirection *)
- malloc(priv->dirsize *
- sizeof(XctHDirection));
- }
- priv->dirstack[data->horz_depth - 1] = data->horizontal;
- if (data->item[1] == 0x31)
- data->horizontal = XctLeftToRight;
- else
- data->horizontal = XctRightToLeft;
- if ((priv->flags & UsedGraphic) &&
- !(priv->flags & UsedDirection))
- return XctError;
- priv->flags |= UsedDirection;
- if (data->flags & XctHideDirection)
- continue;
- return XctHorizontal;
- } else if (data->item_length == 2) {
- if (!data->horz_depth)
- return XctError;
- data->horz_depth--;
- data->horizontal = priv->dirstack[data->horz_depth];
- if (data->flags & XctHideDirection)
- continue;
- return XctHorizontal;
- }
- }
- } else if (data->flags & XctSingleSetSegments) {
- NEXT;
- if IsC0(c) {
- data->encoding = (char *)NULL;
- data->char_size = 1;
- if (IsLegalC0(data, c))
- return XctC0Segment;
- } else if (IsGL(c)) {
- data->encoding = data->GL_encoding;
- data->char_size = data->GL_char_size;
- while (IsMore(priv) && IsGL(*priv->ptr)) {
- NEXT;
- }
- if (((data->char_size > 1) &&
- (data->item_length % data->char_size)) ||
- ((data->horz_depth == 0) &&
- (priv->flags & UsedDirection)))
- return XctError;
- priv->flags |= UsedGraphic;
- return XctGLSegment;
- } else if (IsC1(c)) {
- data->encoding = (char *)NULL;
- data->char_size = 1;
- if (IsLegalC1(data, c))
- return XctC1Segment;
- } else {
- data->encoding = data->GR_encoding;
- data->char_size = data->GR_char_size;
- while (IsMore(priv) && IsGR(*priv->ptr)) {
- NEXT;
- }
- if (((data->char_size > 1) &&
- (data->item_length % data->char_size)) ||
- ((data->horz_depth == 0) &&
- (priv->flags & UsedDirection)))
- return XctError;
- priv->flags |= UsedGraphic;
- if (!(priv->flags & ToGL))
- return XctGRSegment;
- ShiftGRToGL(data, 0);
- return XctGLSegment;
- }
- } else {
- bits = 0;
- while (1) {
- if (IsC0(c) || IsC1(c)) {
- if ((c == ESC) || (c == CSI))
- break;
- if (IsC0(c) ? !IsLegalC0(data, c) : !IsLegalC1(data, c))
- break;
- bits |= HasC;
- NEXT;
- } else {
- len = data->item_length;
- if (IsGL(c)) {
- if ((data->flags & XctShiftMultiGRToGL) &&
- (bits & HasGR))
- break;
- NEXT;
- bits |= HasGL;
- while (IsMore(priv) && IsGL(*priv->ptr)) {
- NEXT;
- }
- if ((data->GL_char_size > 1) &&
- ((data->item_length - len) % data->GL_char_size))
- return XctError;
- } else {
- if ((data->flags & XctShiftMultiGRToGL) &&
- (bits & HasGL))
- break;
- NEXT;
- bits |= HasGR;
- while (IsMore(priv) && IsGR(*priv->ptr)) {
- NEXT;
- }
- if ((data->GR_char_size > 1) &&
- ((data->item_length - len) % data->GR_char_size))
- return XctError;
- }
- }
- if (!IsMore(priv))
- break;
- c = *priv->ptr;
- }
- if (data->item_length) {
- if (bits & (HasGL|HasGR)) {
- priv->flags |= UsedGraphic;
- if ((data->horz_depth == 0) &&
- (priv->flags & UsedDirection))
- return XctError;
- if ((data->flags & XctShiftMultiGRToGL) && (bits & HasGR))
- ShiftGRToGL(data, bits & HasC);
- }
- if ((bits == (HasGL|HasGR)) ||
- (data->GLGR_encoding && !(bits & HasC))) {
- data->encoding = data->GLGR_encoding;
- if (data->GL_char_size == data->GR_char_size)
- data->char_size = data->GL_char_size;
- else
- data->char_size = 0;
- } else if (bits == HasGL) {
- data->encoding = data->GL_encoding;
- data->char_size = data->GL_char_size;
- } else if (bits == HasGR) {
- data->encoding = data->GR_encoding;
- data->char_size = data->GR_char_size;
- } else {
- data->encoding = (char *)NULL;
- data->char_size = 1;
- if ((bits & HasGL) &&
- (data->GL_char_size != data->char_size))
- data->char_size = 0;
- if ((bits & HasGR) &&
- (data->GR_char_size != data->char_size))
- data->char_size = 0;
- }
- return XctSegment;
- }
- NEXT;
- }
- if (data->version <= XctVersion)
- return XctError;
- if (data->flags & XctProvideExtensions)
- return XctExtension;
- if (!data->can_ignore_exts)
- return XctError;
- }
- return XctEndOfText;
-}
-
-/* Free all data associated with an XctDataStructure. */
-void
-XctFree(register XctData data)
-{
- unsigned i;
- register XctPriv priv = data->priv;
-
- if (priv->dirstack)
- free((char *)priv->dirstack);
- if (data->flags & XctFreeString)
- free((char *)data->total_string);
- for (i = 0; i < priv->enc_count; i++)
- free(priv->encodings[i]);
- if (priv->encodings)
- free((char *)priv->encodings);
- if (priv->itembuf)
- free((char *)priv->itembuf);
- free((char *)data);
-}
+/*
+
+Copyright 1989, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/Xfuncs.h>
+#include "Xct.h"
+#include <stdio.h>
+
+#define UsedGraphic 0x0001
+#define UsedDirection 0x0002
+
+typedef struct _XctPriv {
+ XctString ptr;
+ XctString ptrend;
+ unsigned flags;
+ XctHDirection *dirstack;
+ unsigned dirsize;
+ char **encodings;
+ unsigned enc_count;
+ XctString itembuf;
+ unsigned buf_count;
+} *XctPriv;
+
+#define IsMore(priv) ((priv)->ptr != (priv)->ptrend)
+#define AmountLeft(priv) ((priv)->ptrend - (priv)->ptr)
+
+#include <stdlib.h>
+
+#define HT 0x09
+#define NL 0x0a
+#define ESC 0x1b
+#define CSI 0x9b
+
+#define IsLegalC0(data, c) (((c) == HT) || ((c) == NL) || \
+ (((data)->version > XctVersion) && \
+ ((data)->flags & XctAcceptC0Extensions)))
+
+#define IsLegalC1(priv, c) (((data)->version > XctVersion) && \
+ ((data)->flags & XctAcceptC1Extensions))
+
+#define IsI2(c) (((c) >= 0x20) && ((c) <= 0x2f))
+#define IsI3(c) (((c) >= 0x30) && ((c) <= 0x3f))
+#define IsESCF(c) (((c) >= 0x30) && ((c) <= 0x7e))
+#define IsCSIF(c) (((c) >= 0x40) && ((c) <= 0x7e))
+#define IsC0(c) ((c) <= 0x1f)
+#define IsGL(c) (((c) >= 0x20) && ((c) <= 0x7f))
+#define IsC1(c) (((c) >= 0x80) && ((c) <= 0x9f))
+#define IsGR(c) ((c) >= 0xa0)
+
+#define HasC 1
+#define HasGL 2
+#define HasGR 4
+#define ToGL 8
+
+/*
+ * Prototypes
+ */
+static void ComputeGLGR(XctData);
+static int Handle94GR(XctData, int);
+static int Handle96GR(XctData, int);
+static int HandleExtended(XctData data, int);
+static int HandleGL(XctData, int);
+static int HandleMultiGL(XctData, int);
+static int HandleMultiGR(XctData data, int);
+static void ShiftGRToGL(XctData, int);
+
+/*
+ * Implementation
+ */
+static void
+ComputeGLGR(register XctData data)
+{
+ /* XXX this will need more work if more sets are registered */
+ if ((data->GL_set_size == 94) && (data->GL_char_size == 1) &&
+ (data->GL[0] == '\102') &&
+ (data->GR_set_size == 96) && (data->GR_char_size == 1))
+ data->GLGR_encoding = data->GR_encoding;
+ else if ((data->GL_set_size == 94) && (data->GL_char_size == 1) &&
+ (data->GL[0] == '\112') &&
+ (data->GR_set_size == 94) && (data->GR_char_size == 1))
+ data->GLGR_encoding = data->GR_encoding;
+ else
+ data->GLGR_encoding = (char *)NULL;
+}
+
+static int
+HandleGL(register XctData data, int c)
+{
+ switch (c) {
+ case 0x42:
+ data->GL = "\102";
+ data->GL_encoding = "ISO8859-1";
+ break;
+ case 0x4a:
+ data->GL = "\112";
+ data->GL_encoding = "JISX0201.1976-0";
+ break;
+ default:
+ return 0;
+ }
+ data->GL_set_size = 94;
+ data->GL_char_size = 1;
+ ComputeGLGR(data);
+ return 1;
+}
+
+static int
+HandleMultiGL(register XctData data, int c)
+{
+ switch (c) {
+ case 0x41:
+ data->GL = "\101";
+ data->GL_encoding = "GB2312.1980-0";
+ break;
+ case 0x42:
+ data->GL = "\102";
+ data->GL_encoding = "JISX0208.1983-0";
+ break;
+ case 0x43:
+ data->GL = "\103";
+ data->GL_encoding = "KSC5601.1987-0";
+ break;
+ default:
+ return 0;
+ }
+ data->GL_set_size = 94;
+ data->GL_char_size = 2;
+#ifdef notdef
+ if (c < 0x60)
+ data->GL_char_size = 2;
+ else if (c < 0x70)
+ data->GL_char_size = 3;
+ else
+ data->GL_char_size = 4;
+#endif
+ data->GLGR_encoding = (char *)NULL;
+ return 1;
+}
+
+static int
+Handle94GR(register XctData data, int c)
+{
+ switch (c) {
+ case 0x49:
+ data->GR = "\111";
+ data->GR_encoding = "JISX0201.1976-0";
+ break;
+ default:
+ return 0;
+ }
+ data->priv->flags &= ~ToGL;
+ data->GR_set_size = 94;
+ data->GR_char_size = 1;
+ data->GLGR_encoding = (char *)NULL;
+ return 1;
+}
+
+static int
+Handle96GR(register XctData data, int c)
+{
+ switch (c) {
+ case 0x41:
+ data->GR = "\101";
+ data->GR_encoding = "ISO8859-1";
+ break;
+ case 0x42:
+ data->GR = "\102";
+ data->GR_encoding = "ISO8859-2";
+ break;
+ case 0x43:
+ data->GR = "\103";
+ data->GR_encoding = "ISO8859-3";
+ break;
+ case 0x44:
+ data->GR = "\104";
+ data->GR_encoding = "ISO8859-4";
+ break;
+ case 0x46:
+ data->GR = "\106";
+ data->GR_encoding = "ISO8859-7";
+ break;
+ case 0x47:
+ data->GR = "\107";
+ data->GR_encoding = "ISO8859-6";
+ break;
+ case 0x48:
+ data->GR = "\110";
+ data->GR_encoding = "ISO8859-8";
+ break;
+ case 0x4c:
+ data->GR = "\114";
+ data->GR_encoding = "ISO8859-5";
+ break;
+ case 0x4d:
+ data->GR = "\115";
+ data->GR_encoding = "ISO8859-9";
+ break;
+ default:
+ return 0;
+ }
+ data->priv->flags &= ~ToGL;
+ data->GR_set_size = 96;
+ data->GR_char_size = 1;
+ ComputeGLGR(data);
+ return 1;
+}
+
+static int
+HandleMultiGR(register XctData data, int c)
+{
+ switch (c) {
+ case 0x41:
+ data->GR = "\101";
+ if (data->flags & XctShiftMultiGRToGL)
+ data->GR_encoding = "GB2312.1980-0";
+ else
+ data->GR_encoding = "GB2312.1980-1";
+ break;
+ case 0x42:
+ data->GR = "\102";
+ if (data->flags & XctShiftMultiGRToGL)
+ data->GR_encoding = "JISX0208.1983-0";
+ else
+ data->GR_encoding = "JISX0208.1983-1";
+ break;
+ case 0x43:
+ data->GR = "\103";
+ if (data->flags & XctShiftMultiGRToGL)
+ data->GR_encoding = "KSC5601.1987-0";
+ else
+ data->GR_encoding = "KSC5601.1987-1";
+ break;
+ default:
+ return 0;
+ }
+ if (data->flags & XctShiftMultiGRToGL)
+ data->priv->flags |= ToGL;
+ else
+ data->priv->flags &= ~ToGL;
+ data->GR_set_size = 94;
+ data->GR_char_size = 2;
+#ifdef notdef
+ if (c < 0x60)
+ data->GR_char_size = 2;
+ else if (c < 0x70)
+ data->GR_char_size = 3;
+ else
+ data->GR_char_size = 4;
+#endif
+ data->GLGR_encoding = (char *)NULL;
+ return 1;
+}
+
+static int
+HandleExtended(register XctData data, int c)
+{
+ register XctPriv priv = data->priv;
+ XctString enc = data->item + 6;
+ register XctString ptr = enc;
+ unsigned i, len;
+
+ while (*ptr != 0x02) {
+ if (!*ptr || (++ptr == priv->ptr))
+ return 0;
+ }
+ data->item = ptr + 1;
+ data->item_length = priv->ptr - data->item;
+ len = ptr - enc;
+ for (i = 0;
+ (i < priv->enc_count) &&
+ strncmp(priv->encodings[i], (char *)enc, len);
+ i++)
+ ;
+ if (i == priv->enc_count) {
+ XctString cp;
+
+ for (cp = enc; cp != ptr; cp++) {
+ if ((!IsGL(*cp) && !IsGR(*cp)) || (*cp == 0x2a) || (*cp == 0x3f))
+ return 0;
+ }
+ ptr = (XctString)malloc((unsigned)len + 1);
+ (void) memmove((char *)ptr, (char *)enc, len);
+ ptr[len] = 0x00;
+ priv->enc_count++;
+ if (priv->encodings)
+ priv->encodings = (char **)realloc(
+ (char *)priv->encodings,
+ priv->enc_count * sizeof(char *));
+ else
+ priv->encodings = (char **)malloc(sizeof(char *));
+ priv->encodings[i] = (char *)ptr;
+ }
+ data->encoding = priv->encodings[i];
+ data->char_size = c - 0x30;
+ return 1;
+}
+
+static void
+ShiftGRToGL(register XctData data, int hasCdata)
+{
+ register XctPriv priv = data->priv;
+ register int i;
+
+ if (data->item_length > priv->buf_count) {
+ priv->buf_count = data->item_length;
+ if (priv->itembuf)
+ priv->itembuf = (XctString)realloc((char *)priv->itembuf,
+ priv->buf_count);
+ else
+ priv->itembuf = (XctString)malloc(priv->buf_count);
+ }
+ (void) memmove((char *)priv->itembuf, (char *)data->item,
+ data->item_length);
+ data->item = priv->itembuf;
+ if (hasCdata) {
+ for (i = data->item_length; --i >= 0; ) {
+ if (IsGR(data->item[i]))
+ data->item[i] &= 0x7f;
+ }
+ } else {
+ for (i = data->item_length; --i >= 0; )
+ data->item[i] &= 0x7f;
+ }
+}
+
+/* Create an XctData structure for parsing a Compound Text string. */
+XctData
+XctCreate(_Xconst unsigned char *string, int length, XctFlags flags)
+{
+ register XctData data;
+ register XctPriv priv;
+
+ data = (XctData)malloc(sizeof(struct _XctRec) + sizeof(struct _XctPriv));
+ if (!data)
+ return data;
+ data->priv = priv = (XctPriv)(data + 1);
+ data->total_string = (XctString)string;
+ data->total_length = length;
+ data->flags = flags;
+ priv->dirstack = (XctHDirection *)NULL;
+ priv->dirsize = 0;
+ priv->encodings = (char **)NULL;
+ priv->enc_count = 0;
+ priv->itembuf = (XctString)NULL;
+ priv->buf_count = 0;
+ XctReset(data);
+ return data;
+}
+
+/* Reset the XctData structure to re-parse the string from the beginning. */
+void
+XctReset(register XctData data)
+{
+ register XctPriv priv = data->priv;
+
+ priv->ptr = data->total_string;
+ priv->ptrend = data->total_string + data->total_length;
+ data->item = (XctString)NULL;
+ data->item_length = 0;
+ data->encoding = (char *)NULL;
+ data->char_size = 1;
+ data->horizontal = XctUnspecified;
+ data->horz_depth = 0;
+ priv->flags = 0;
+ data->GL_set_size = data->GR_set_size = 0; /* XXX */
+ (void)HandleGL(data, (unsigned char)0x42);
+ (void)Handle96GR(data, (unsigned char)0x41);
+ data->version = 1;
+ data->can_ignore_exts = 0;
+ /* parse version, if present */
+ if ((data->total_length >= 4) &&
+ (priv->ptr[0] == ESC) && (priv->ptr[1] == 0x23) &&
+ IsI2(priv->ptr[2]) &&
+ ((priv->ptr[3] == 0x30) || (priv->ptr[3] == 0x31))) {
+ data->version = priv->ptr[2] - 0x1f;
+ if (priv->ptr[3] == 0x30)
+ data->can_ignore_exts = 1;
+ priv->ptr += 4;
+ }
+}
+
+/* Parse the next "item" from the Compound Text string. The return value
+ * indicates what kind of item is returned. The item itself, and the current
+ * contextual state, are reported as components of the XctData structure.
+ */
+XctResult
+XctNextItem(register XctData data)
+{
+ register XctPriv priv = data->priv;
+ unsigned char c;
+ int len, bits;
+
+#define NEXT data->item_length++; priv->ptr++
+
+ while (IsMore(priv)) {
+ data->item = priv->ptr;
+ data->item_length = 0;
+ c = *priv->ptr;
+ if (c == ESC) {
+ NEXT;
+ while (IsMore(priv) && IsI2(*priv->ptr)) {
+ NEXT;
+ }
+ if (!IsMore(priv))
+ return XctError;
+ c = *priv->ptr;
+ NEXT;
+ if (!IsESCF(c))
+ return XctError;
+ switch (data->item[1]) {
+ case 0x24:
+ if (data->item_length > 3) {
+ if (data->item[2] == 0x28) {
+ if (HandleMultiGL(data, c))
+ continue;
+ } else if (data->item[2] == 0x29) {
+ if (HandleMultiGR(data, c))
+ continue;
+ }
+ }
+ break;
+ case 0x25:
+ if ((data->item_length == 4) && (data->item[2] == 0x2f) &&
+ (c <= 0x3f)) {
+ if ((AmountLeft(priv) < 2) ||
+ (priv->ptr[0] < 0x80) || (priv->ptr[1] < 0x80))
+ return XctError;
+ len = *priv->ptr - 0x80;
+ NEXT;
+ len = (len << 7) + (*priv->ptr - 0x80);
+ NEXT;
+ if (AmountLeft(priv) < len)
+ return XctError;
+ data->item_length += len;
+ priv->ptr += len;
+ if (c <= 0x34) {
+ if (!HandleExtended(data, c) ||
+ ((data->horz_depth == 0) &&
+ (priv->flags & UsedDirection)))
+ return XctError;
+ priv->flags |= UsedGraphic;
+ return XctExtendedSegment;
+ }
+ }
+ break;
+ case 0x28:
+ if (HandleGL(data, c))
+ continue;
+ break;
+ case 0x29:
+ if (Handle94GR(data, c))
+ continue;
+ break;
+ case 0x2d:
+ if (Handle96GR(data, c))
+ continue;
+ break;
+ }
+ } else if (c == CSI) {
+ NEXT;
+ while (IsMore(priv) && IsI3(*priv->ptr)) {
+ NEXT;
+ }
+ while (IsMore(priv) && IsI2(*priv->ptr)) {
+ NEXT;
+ }
+ if (!IsMore(priv))
+ return XctError;
+ c = *priv->ptr;
+ NEXT;
+ if (!IsCSIF(c))
+ return XctError;
+ if (c == 0x5d) {
+ if ((data->item_length == 3) &&
+ ((data->item[1] == 0x31) || (data->item[1] == 0x32))) {
+ data->horz_depth++;
+ if (priv->dirsize < data->horz_depth) {
+ priv->dirsize += 10;
+ if (priv->dirstack)
+ priv->dirstack = (XctHDirection *)
+ realloc((char *)priv->dirstack,
+ priv->dirsize *
+ sizeof(XctHDirection));
+ else
+ priv->dirstack = (XctHDirection *)
+ malloc(priv->dirsize *
+ sizeof(XctHDirection));
+ }
+ priv->dirstack[data->horz_depth - 1] = data->horizontal;
+ if (data->item[1] == 0x31)
+ data->horizontal = XctLeftToRight;
+ else
+ data->horizontal = XctRightToLeft;
+ if ((priv->flags & UsedGraphic) &&
+ !(priv->flags & UsedDirection))
+ return XctError;
+ priv->flags |= UsedDirection;
+ if (data->flags & XctHideDirection)
+ continue;
+ return XctHorizontal;
+ } else if (data->item_length == 2) {
+ if (!data->horz_depth)
+ return XctError;
+ data->horz_depth--;
+ data->horizontal = priv->dirstack[data->horz_depth];
+ if (data->flags & XctHideDirection)
+ continue;
+ return XctHorizontal;
+ }
+ }
+ } else if (data->flags & XctSingleSetSegments) {
+ NEXT;
+ if IsC0(c) {
+ data->encoding = (char *)NULL;
+ data->char_size = 1;
+ if (IsLegalC0(data, c))
+ return XctC0Segment;
+ } else if (IsGL(c)) {
+ data->encoding = data->GL_encoding;
+ data->char_size = data->GL_char_size;
+ while (IsMore(priv) && IsGL(*priv->ptr)) {
+ NEXT;
+ }
+ if (((data->char_size > 1) &&
+ (data->item_length % data->char_size)) ||
+ ((data->horz_depth == 0) &&
+ (priv->flags & UsedDirection)))
+ return XctError;
+ priv->flags |= UsedGraphic;
+ return XctGLSegment;
+ } else if (IsC1(c)) {
+ data->encoding = (char *)NULL;
+ data->char_size = 1;
+ if (IsLegalC1(data, c))
+ return XctC1Segment;
+ } else {
+ data->encoding = data->GR_encoding;
+ data->char_size = data->GR_char_size;
+ while (IsMore(priv) && IsGR(*priv->ptr)) {
+ NEXT;
+ }
+ if (((data->char_size > 1) &&
+ (data->item_length % data->char_size)) ||
+ ((data->horz_depth == 0) &&
+ (priv->flags & UsedDirection)))
+ return XctError;
+ priv->flags |= UsedGraphic;
+ if (!(priv->flags & ToGL))
+ return XctGRSegment;
+ ShiftGRToGL(data, 0);
+ return XctGLSegment;
+ }
+ } else {
+ bits = 0;
+ while (1) {
+ if (IsC0(c) || IsC1(c)) {
+ if ((c == ESC) || (c == CSI))
+ break;
+ if (IsC0(c) ? !IsLegalC0(data, c) : !IsLegalC1(data, c))
+ break;
+ bits |= HasC;
+ NEXT;
+ } else {
+ len = data->item_length;
+ if (IsGL(c)) {
+ if ((data->flags & XctShiftMultiGRToGL) &&
+ (bits & HasGR))
+ break;
+ NEXT;
+ bits |= HasGL;
+ while (IsMore(priv) && IsGL(*priv->ptr)) {
+ NEXT;
+ }
+ if ((data->GL_char_size > 1) &&
+ ((data->item_length - len) % data->GL_char_size))
+ return XctError;
+ } else {
+ if ((data->flags & XctShiftMultiGRToGL) &&
+ (bits & HasGL))
+ break;
+ NEXT;
+ bits |= HasGR;
+ while (IsMore(priv) && IsGR(*priv->ptr)) {
+ NEXT;
+ }
+ if ((data->GR_char_size > 1) &&
+ ((data->item_length - len) % data->GR_char_size))
+ return XctError;
+ }
+ }
+ if (!IsMore(priv))
+ break;
+ c = *priv->ptr;
+ }
+ if (data->item_length) {
+ if (bits & (HasGL|HasGR)) {
+ priv->flags |= UsedGraphic;
+ if ((data->horz_depth == 0) &&
+ (priv->flags & UsedDirection))
+ return XctError;
+ if ((data->flags & XctShiftMultiGRToGL) && (bits & HasGR))
+ ShiftGRToGL(data, bits & HasC);
+ }
+ if ((bits == (HasGL|HasGR)) ||
+ (data->GLGR_encoding && !(bits & HasC))) {
+ data->encoding = data->GLGR_encoding;
+ if (data->GL_char_size == data->GR_char_size)
+ data->char_size = data->GL_char_size;
+ else
+ data->char_size = 0;
+ } else if (bits == HasGL) {
+ data->encoding = data->GL_encoding;
+ data->char_size = data->GL_char_size;
+ } else if (bits == HasGR) {
+ data->encoding = data->GR_encoding;
+ data->char_size = data->GR_char_size;
+ } else {
+ data->encoding = (char *)NULL;
+ data->char_size = 1;
+ if ((bits & HasGL) &&
+ (data->GL_char_size != data->char_size))
+ data->char_size = 0;
+ if ((bits & HasGR) &&
+ (data->GR_char_size != data->char_size))
+ data->char_size = 0;
+ }
+ return XctSegment;
+ }
+ NEXT;
+ }
+ if (data->version <= XctVersion)
+ return XctError;
+ if (data->flags & XctProvideExtensions)
+ return XctExtension;
+ if (!data->can_ignore_exts)
+ return XctError;
+ }
+ return XctEndOfText;
+}
+
+/* Free all data associated with an XctDataStructure. */
+void
+XctFree(register XctData data)
+{
+ unsigned i;
+ register XctPriv priv = data->priv;
+
+ if (priv->dirstack)
+ free((char *)priv->dirstack);
+ if (data->flags & XctFreeString)
+ free((char *)data->total_string);
+ for (i = 0; i < priv->enc_count; i++)
+ free(priv->encodings[i]);
+ if (priv->encodings)
+ free((char *)priv->encodings);
+ if (priv->itembuf)
+ free((char *)priv->itembuf);
+ free((char *)data);
+}