diff options
Diffstat (limited to 'libXmu/src/Xct.c')
-rw-r--r-- | libXmu/src/Xct.c | 1368 |
1 files changed, 684 insertions, 684 deletions
diff --git a/libXmu/src/Xct.c b/libXmu/src/Xct.c index 258554c3a..1db470ebb 100644 --- a/libXmu/src/Xct.c +++ b/libXmu/src/Xct.c @@ -1,684 +1,684 @@ -/*
-
-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);
-}
+/* + +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); +} |