00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <X11/Xfuncs.h>
00031 #include "Xct.h"
00032 #include <stdio.h>
00033
00034 #define UsedGraphic 0x0001
00035 #define UsedDirection 0x0002
00036
00037 typedef struct _XctPriv {
00038 XctString ptr;
00039 XctString ptrend;
00040 unsigned flags;
00041 XctHDirection *dirstack;
00042 unsigned dirsize;
00043 char **encodings;
00044 unsigned enc_count;
00045 XctString itembuf;
00046 unsigned buf_count;
00047 } *XctPriv;
00048
00049 #define IsMore(priv) ((priv)->ptr != (priv)->ptrend)
00050 #define AmountLeft(priv) ((priv)->ptrend - (priv)->ptr)
00051
00052 #include <stdlib.h>
00053
00054 #define HT 0x09
00055 #define NL 0x0a
00056 #define ESC 0x1b
00057 #define CSI 0x9b
00058
00059 #define IsLegalC0(data, c) (((c) == HT) || ((c) == NL) || \
00060 (((data)->version > XctVersion) && \
00061 ((data)->flags & XctAcceptC0Extensions)))
00062
00063 #define IsLegalC1(priv, c) (((data)->version > XctVersion) && \
00064 ((data)->flags & XctAcceptC1Extensions))
00065
00066 #define IsI2(c) (((c) >= 0x20) && ((c) <= 0x2f))
00067 #define IsI3(c) (((c) >= 0x30) && ((c) <= 0x3f))
00068 #define IsESCF(c) (((c) >= 0x30) && ((c) <= 0x7e))
00069 #define IsCSIF(c) (((c) >= 0x40) && ((c) <= 0x7e))
00070 #define IsC0(c) ((c) <= 0x1f)
00071 #define IsGL(c) (((c) >= 0x20) && ((c) <= 0x7f))
00072 #define IsC1(c) (((c) >= 0x80) && ((c) <= 0x9f))
00073 #define IsGR(c) ((c) >= 0xa0)
00074
00075 #define HasC 1
00076 #define HasGL 2
00077 #define HasGR 4
00078 #define ToGL 8
00079
00080
00081
00082
00083 static void ComputeGLGR(XctData);
00084 static int Handle94GR(XctData, int);
00085 static int Handle96GR(XctData, int);
00086 static int HandleExtended(XctData data, int);
00087 static int HandleGL(XctData, int);
00088 static int HandleMultiGL(XctData, int);
00089 static int HandleMultiGR(XctData data, int);
00090 static void ShiftGRToGL(XctData, int);
00091
00092
00093
00094
00095 static void
00096 ComputeGLGR(register XctData data)
00097 {
00098
00099 if ((data->GL_set_size == 94) && (data->GL_char_size == 1) &&
00100 (data->GL[0] == '\102') &&
00101 (data->GR_set_size == 96) && (data->GR_char_size == 1))
00102 data->GLGR_encoding = data->GR_encoding;
00103 else if ((data->GL_set_size == 94) && (data->GL_char_size == 1) &&
00104 (data->GL[0] == '\112') &&
00105 (data->GR_set_size == 94) && (data->GR_char_size == 1))
00106 data->GLGR_encoding = data->GR_encoding;
00107 else
00108 data->GLGR_encoding = (char *)NULL;
00109 }
00110
00111 static int
00112 HandleGL(register XctData data, int c)
00113 {
00114 switch (c) {
00115 case 0x42:
00116 data->GL = "\102";
00117 data->GL_encoding = "ISO8859-1";
00118 break;
00119 case 0x4a:
00120 data->GL = "\112";
00121 data->GL_encoding = "JISX0201.1976-0";
00122 break;
00123 default:
00124 return 0;
00125 }
00126 data->GL_set_size = 94;
00127 data->GL_char_size = 1;
00128 ComputeGLGR(data);
00129 return 1;
00130 }
00131
00132 static int
00133 HandleMultiGL(register XctData data, int c)
00134 {
00135 switch (c) {
00136 case 0x41:
00137 data->GL = "\101";
00138 data->GL_encoding = "GB2312.1980-0";
00139 break;
00140 case 0x42:
00141 data->GL = "\102";
00142 data->GL_encoding = "JISX0208.1983-0";
00143 break;
00144 case 0x43:
00145 data->GL = "\103";
00146 data->GL_encoding = "KSC5601.1987-0";
00147 break;
00148 default:
00149 return 0;
00150 }
00151 data->GL_set_size = 94;
00152 data->GL_char_size = 2;
00153 #ifdef notdef
00154 if (c < 0x60)
00155 data->GL_char_size = 2;
00156 else if (c < 0x70)
00157 data->GL_char_size = 3;
00158 else
00159 data->GL_char_size = 4;
00160 #endif
00161 data->GLGR_encoding = (char *)NULL;
00162 return 1;
00163 }
00164
00165 static int
00166 Handle94GR(register XctData data, int c)
00167 {
00168 switch (c) {
00169 case 0x49:
00170 data->GR = "\111";
00171 data->GR_encoding = "JISX0201.1976-0";
00172 break;
00173 default:
00174 return 0;
00175 }
00176 data->priv->flags &= ~ToGL;
00177 data->GR_set_size = 94;
00178 data->GR_char_size = 1;
00179 data->GLGR_encoding = (char *)NULL;
00180 return 1;
00181 }
00182
00183 static int
00184 Handle96GR(register XctData data, int c)
00185 {
00186 switch (c) {
00187 case 0x41:
00188 data->GR = "\101";
00189 data->GR_encoding = "ISO8859-1";
00190 break;
00191 case 0x42:
00192 data->GR = "\102";
00193 data->GR_encoding = "ISO8859-2";
00194 break;
00195 case 0x43:
00196 data->GR = "\103";
00197 data->GR_encoding = "ISO8859-3";
00198 break;
00199 case 0x44:
00200 data->GR = "\104";
00201 data->GR_encoding = "ISO8859-4";
00202 break;
00203 case 0x46:
00204 data->GR = "\106";
00205 data->GR_encoding = "ISO8859-7";
00206 break;
00207 case 0x47:
00208 data->GR = "\107";
00209 data->GR_encoding = "ISO8859-6";
00210 break;
00211 case 0x48:
00212 data->GR = "\110";
00213 data->GR_encoding = "ISO8859-8";
00214 break;
00215 case 0x4c:
00216 data->GR = "\114";
00217 data->GR_encoding = "ISO8859-5";
00218 break;
00219 case 0x4d:
00220 data->GR = "\115";
00221 data->GR_encoding = "ISO8859-9";
00222 break;
00223 default:
00224 return 0;
00225 }
00226 data->priv->flags &= ~ToGL;
00227 data->GR_set_size = 96;
00228 data->GR_char_size = 1;
00229 ComputeGLGR(data);
00230 return 1;
00231 }
00232
00233 static int
00234 HandleMultiGR(register XctData data, int c)
00235 {
00236 switch (c) {
00237 case 0x41:
00238 data->GR = "\101";
00239 if (data->flags & XctShiftMultiGRToGL)
00240 data->GR_encoding = "GB2312.1980-0";
00241 else
00242 data->GR_encoding = "GB2312.1980-1";
00243 break;
00244 case 0x42:
00245 data->GR = "\102";
00246 if (data->flags & XctShiftMultiGRToGL)
00247 data->GR_encoding = "JISX0208.1983-0";
00248 else
00249 data->GR_encoding = "JISX0208.1983-1";
00250 break;
00251 case 0x43:
00252 data->GR = "\103";
00253 if (data->flags & XctShiftMultiGRToGL)
00254 data->GR_encoding = "KSC5601.1987-0";
00255 else
00256 data->GR_encoding = "KSC5601.1987-1";
00257 break;
00258 default:
00259 return 0;
00260 }
00261 if (data->flags & XctShiftMultiGRToGL)
00262 data->priv->flags |= ToGL;
00263 else
00264 data->priv->flags &= ~ToGL;
00265 data->GR_set_size = 94;
00266 data->GR_char_size = 2;
00267 #ifdef notdef
00268 if (c < 0x60)
00269 data->GR_char_size = 2;
00270 else if (c < 0x70)
00271 data->GR_char_size = 3;
00272 else
00273 data->GR_char_size = 4;
00274 #endif
00275 data->GLGR_encoding = (char *)NULL;
00276 return 1;
00277 }
00278
00279 static int
00280 HandleExtended(register XctData data, int c)
00281 {
00282 register XctPriv priv = data->priv;
00283 XctString enc = data->item + 6;
00284 register XctString ptr = enc;
00285 unsigned i, len;
00286
00287 while (*ptr != 0x02) {
00288 if (!*ptr || (++ptr == priv->ptr))
00289 return 0;
00290 }
00291 data->item = ptr + 1;
00292 data->item_length = priv->ptr - data->item;
00293 len = ptr - enc;
00294 for (i = 0;
00295 (i < priv->enc_count) &&
00296 strncmp(priv->encodings[i], (char *)enc, len);
00297 i++)
00298 ;
00299 if (i == priv->enc_count) {
00300 XctString cp;
00301
00302 for (cp = enc; cp != ptr; cp++) {
00303 if ((!IsGL(*cp) && !IsGR(*cp)) || (*cp == 0x2a) || (*cp == 0x3f))
00304 return 0;
00305 }
00306 ptr = (XctString)malloc((unsigned)len + 1);
00307 (void) memmove((char *)ptr, (char *)enc, len);
00308 ptr[len] = 0x00;
00309 priv->enc_count++;
00310 if (priv->encodings)
00311 priv->encodings = (char **)realloc(
00312 (char *)priv->encodings,
00313 priv->enc_count * sizeof(char *));
00314 else
00315 priv->encodings = (char **)malloc(sizeof(char *));
00316 priv->encodings[i] = (char *)ptr;
00317 }
00318 data->encoding = priv->encodings[i];
00319 data->char_size = c - 0x30;
00320 return 1;
00321 }
00322
00323 static void
00324 ShiftGRToGL(register XctData data, int hasCdata)
00325 {
00326 register XctPriv priv = data->priv;
00327 register int i;
00328
00329 if (data->item_length > priv->buf_count) {
00330 priv->buf_count = data->item_length;
00331 if (priv->itembuf)
00332 priv->itembuf = (XctString)realloc((char *)priv->itembuf,
00333 priv->buf_count);
00334 else
00335 priv->itembuf = (XctString)malloc(priv->buf_count);
00336 }
00337 (void) memmove((char *)priv->itembuf, (char *)data->item,
00338 data->item_length);
00339 data->item = priv->itembuf;
00340 if (hasCdata) {
00341 for (i = data->item_length; --i >= 0; ) {
00342 if (IsGR(data->item[i]))
00343 data->item[i] &= 0x7f;
00344 }
00345 } else {
00346 for (i = data->item_length; --i >= 0; )
00347 data->item[i] &= 0x7f;
00348 }
00349 }
00350
00351
00352 XctData
00353 XctCreate(_Xconst unsigned char *string, int length, XctFlags flags)
00354 {
00355 register XctData data;
00356 register XctPriv priv;
00357
00358 data = (XctData)malloc(sizeof(struct _XctRec) + sizeof(struct _XctPriv));
00359 if (!data)
00360 return data;
00361 data->priv = priv = (XctPriv)(data + 1);
00362 data->total_string = (XctString)string;
00363 data->total_length = length;
00364 data->flags = flags;
00365 priv->dirstack = (XctHDirection *)NULL;
00366 priv->dirsize = 0;
00367 priv->encodings = (char **)NULL;
00368 priv->enc_count = 0;
00369 priv->itembuf = (XctString)NULL;
00370 priv->buf_count = 0;
00371 XctReset(data);
00372 return data;
00373 }
00374
00375
00376 void
00377 XctReset(register XctData data)
00378 {
00379 register XctPriv priv = data->priv;
00380
00381 priv->ptr = data->total_string;
00382 priv->ptrend = data->total_string + data->total_length;
00383 data->item = (XctString)NULL;
00384 data->item_length = 0;
00385 data->encoding = (char *)NULL;
00386 data->char_size = 1;
00387 data->horizontal = XctUnspecified;
00388 data->horz_depth = 0;
00389 priv->flags = 0;
00390 data->GL_set_size = data->GR_set_size = 0;
00391 (void)HandleGL(data, (unsigned char)0x42);
00392 (void)Handle96GR(data, (unsigned char)0x41);
00393 data->version = 1;
00394 data->can_ignore_exts = 0;
00395
00396 if ((data->total_length >= 4) &&
00397 (priv->ptr[0] == ESC) && (priv->ptr[1] == 0x23) &&
00398 IsI2(priv->ptr[2]) &&
00399 ((priv->ptr[3] == 0x30) || (priv->ptr[3] == 0x31))) {
00400 data->version = priv->ptr[2] - 0x1f;
00401 if (priv->ptr[3] == 0x30)
00402 data->can_ignore_exts = 1;
00403 priv->ptr += 4;
00404 }
00405 }
00406
00407
00408
00409
00410
00411 XctResult
00412 XctNextItem(register XctData data)
00413 {
00414 register XctPriv priv = data->priv;
00415 unsigned char c;
00416 int len, bits;
00417
00418 #define NEXT data->item_length++; priv->ptr++
00419
00420 while (IsMore(priv)) {
00421 data->item = priv->ptr;
00422 data->item_length = 0;
00423 c = *priv->ptr;
00424 if (c == ESC) {
00425 NEXT;
00426 while (IsMore(priv) && IsI2(*priv->ptr)) {
00427 NEXT;
00428 }
00429 if (!IsMore(priv))
00430 return XctError;
00431 c = *priv->ptr;
00432 NEXT;
00433 if (!IsESCF(c))
00434 return XctError;
00435 switch (data->item[1]) {
00436 case 0x24:
00437 if (data->item_length > 3) {
00438 if (data->item[2] == 0x28) {
00439 if (HandleMultiGL(data, c))
00440 continue;
00441 } else if (data->item[2] == 0x29) {
00442 if (HandleMultiGR(data, c))
00443 continue;
00444 }
00445 }
00446 break;
00447 case 0x25:
00448 if ((data->item_length == 4) && (data->item[2] == 0x2f) &&
00449 (c <= 0x3f)) {
00450 if ((AmountLeft(priv) < 2) ||
00451 (priv->ptr[0] < 0x80) || (priv->ptr[1] < 0x80))
00452 return XctError;
00453 len = *priv->ptr - 0x80;
00454 NEXT;
00455 len = (len << 7) + (*priv->ptr - 0x80);
00456 NEXT;
00457 if (AmountLeft(priv) < len)
00458 return XctError;
00459 data->item_length += len;
00460 priv->ptr += len;
00461 if (c <= 0x34) {
00462 if (!HandleExtended(data, c) ||
00463 ((data->horz_depth == 0) &&
00464 (priv->flags & UsedDirection)))
00465 return XctError;
00466 priv->flags |= UsedGraphic;
00467 return XctExtendedSegment;
00468 }
00469 }
00470 break;
00471 case 0x28:
00472 if (HandleGL(data, c))
00473 continue;
00474 break;
00475 case 0x29:
00476 if (Handle94GR(data, c))
00477 continue;
00478 break;
00479 case 0x2d:
00480 if (Handle96GR(data, c))
00481 continue;
00482 break;
00483 }
00484 } else if (c == CSI) {
00485 NEXT;
00486 while (IsMore(priv) && IsI3(*priv->ptr)) {
00487 NEXT;
00488 }
00489 while (IsMore(priv) && IsI2(*priv->ptr)) {
00490 NEXT;
00491 }
00492 if (!IsMore(priv))
00493 return XctError;
00494 c = *priv->ptr;
00495 NEXT;
00496 if (!IsCSIF(c))
00497 return XctError;
00498 if (c == 0x5d) {
00499 if ((data->item_length == 3) &&
00500 ((data->item[1] == 0x31) || (data->item[1] == 0x32))) {
00501 data->horz_depth++;
00502 if (priv->dirsize < data->horz_depth) {
00503 priv->dirsize += 10;
00504 if (priv->dirstack)
00505 priv->dirstack = (XctHDirection *)
00506 realloc((char *)priv->dirstack,
00507 priv->dirsize *
00508 sizeof(XctHDirection));
00509 else
00510 priv->dirstack = (XctHDirection *)
00511 malloc(priv->dirsize *
00512 sizeof(XctHDirection));
00513 }
00514 priv->dirstack[data->horz_depth - 1] = data->horizontal;
00515 if (data->item[1] == 0x31)
00516 data->horizontal = XctLeftToRight;
00517 else
00518 data->horizontal = XctRightToLeft;
00519 if ((priv->flags & UsedGraphic) &&
00520 !(priv->flags & UsedDirection))
00521 return XctError;
00522 priv->flags |= UsedDirection;
00523 if (data->flags & XctHideDirection)
00524 continue;
00525 return XctHorizontal;
00526 } else if (data->item_length == 2) {
00527 if (!data->horz_depth)
00528 return XctError;
00529 data->horz_depth--;
00530 data->horizontal = priv->dirstack[data->horz_depth];
00531 if (data->flags & XctHideDirection)
00532 continue;
00533 return XctHorizontal;
00534 }
00535 }
00536 } else if (data->flags & XctSingleSetSegments) {
00537 NEXT;
00538 if IsC0(c) {
00539 data->encoding = (char *)NULL;
00540 data->char_size = 1;
00541 if (IsLegalC0(data, c))
00542 return XctC0Segment;
00543 } else if (IsGL(c)) {
00544 data->encoding = data->GL_encoding;
00545 data->char_size = data->GL_char_size;
00546 while (IsMore(priv) && IsGL(*priv->ptr)) {
00547 NEXT;
00548 }
00549 if (((data->char_size > 1) &&
00550 (data->item_length % data->char_size)) ||
00551 ((data->horz_depth == 0) &&
00552 (priv->flags & UsedDirection)))
00553 return XctError;
00554 priv->flags |= UsedGraphic;
00555 return XctGLSegment;
00556 } else if (IsC1(c)) {
00557 data->encoding = (char *)NULL;
00558 data->char_size = 1;
00559 if (IsLegalC1(data, c))
00560 return XctC1Segment;
00561 } else {
00562 data->encoding = data->GR_encoding;
00563 data->char_size = data->GR_char_size;
00564 while (IsMore(priv) && IsGR(*priv->ptr)) {
00565 NEXT;
00566 }
00567 if (((data->char_size > 1) &&
00568 (data->item_length % data->char_size)) ||
00569 ((data->horz_depth == 0) &&
00570 (priv->flags & UsedDirection)))
00571 return XctError;
00572 priv->flags |= UsedGraphic;
00573 if (!(priv->flags & ToGL))
00574 return XctGRSegment;
00575 ShiftGRToGL(data, 0);
00576 return XctGLSegment;
00577 }
00578 } else {
00579 bits = 0;
00580 while (1) {
00581 if (IsC0(c) || IsC1(c)) {
00582 if ((c == ESC) || (c == CSI))
00583 break;
00584 if (IsC0(c) ? !IsLegalC0(data, c) : !IsLegalC1(data, c))
00585 break;
00586 bits |= HasC;
00587 NEXT;
00588 } else {
00589 len = data->item_length;
00590 if (IsGL(c)) {
00591 if ((data->flags & XctShiftMultiGRToGL) &&
00592 (bits & HasGR))
00593 break;
00594 NEXT;
00595 bits |= HasGL;
00596 while (IsMore(priv) && IsGL(*priv->ptr)) {
00597 NEXT;
00598 }
00599 if ((data->GL_char_size > 1) &&
00600 ((data->item_length - len) % data->GL_char_size))
00601 return XctError;
00602 } else {
00603 if ((data->flags & XctShiftMultiGRToGL) &&
00604 (bits & HasGL))
00605 break;
00606 NEXT;
00607 bits |= HasGR;
00608 while (IsMore(priv) && IsGR(*priv->ptr)) {
00609 NEXT;
00610 }
00611 if ((data->GR_char_size > 1) &&
00612 ((data->item_length - len) % data->GR_char_size))
00613 return XctError;
00614 }
00615 }
00616 if (!IsMore(priv))
00617 break;
00618 c = *priv->ptr;
00619 }
00620 if (data->item_length) {
00621 if (bits & (HasGL|HasGR)) {
00622 priv->flags |= UsedGraphic;
00623 if ((data->horz_depth == 0) &&
00624 (priv->flags & UsedDirection))
00625 return XctError;
00626 if ((data->flags & XctShiftMultiGRToGL) && (bits & HasGR))
00627 ShiftGRToGL(data, bits & HasC);
00628 }
00629 if ((bits == (HasGL|HasGR)) ||
00630 (data->GLGR_encoding && !(bits & HasC))) {
00631 data->encoding = data->GLGR_encoding;
00632 if (data->GL_char_size == data->GR_char_size)
00633 data->char_size = data->GL_char_size;
00634 else
00635 data->char_size = 0;
00636 } else if (bits == HasGL) {
00637 data->encoding = data->GL_encoding;
00638 data->char_size = data->GL_char_size;
00639 } else if (bits == HasGR) {
00640 data->encoding = data->GR_encoding;
00641 data->char_size = data->GR_char_size;
00642 } else {
00643 data->encoding = (char *)NULL;
00644 data->char_size = 1;
00645 if ((bits & HasGL) &&
00646 (data->GL_char_size != data->char_size))
00647 data->char_size = 0;
00648 if ((bits & HasGR) &&
00649 (data->GR_char_size != data->char_size))
00650 data->char_size = 0;
00651 }
00652 return XctSegment;
00653 }
00654 NEXT;
00655 }
00656 if (data->version <= XctVersion)
00657 return XctError;
00658 if (data->flags & XctProvideExtensions)
00659 return XctExtension;
00660 if (!data->can_ignore_exts)
00661 return XctError;
00662 }
00663 return XctEndOfText;
00664 }
00665
00666
00667 void
00668 XctFree(register XctData data)
00669 {
00670 unsigned i;
00671 register XctPriv priv = data->priv;
00672
00673 if (priv->dirstack)
00674 free((char *)priv->dirstack);
00675 if (data->flags & XctFreeString)
00676 free((char *)data->total_string);
00677 for (i = 0; i < priv->enc_count; i++)
00678 free(priv->encodings[i]);
00679 if (priv->encodings)
00680 free((char *)priv->encodings);
00681 if (priv->itembuf)
00682 free((char *)priv->itembuf);
00683 free((char *)data);
00684 }