📄 iso.multibyte.c
字号:
#if !defined(lint) && defined(SCCSIDS)static char *sccsid = "@(#)iso.multibyte.c 1.1 92/07/30 SMI";#endif #include <sys/types.h>#include "codeset.h"#include "mbextern.h"#include "iso2022.h"#define TO_MULTI 2#define TO_SINGLE 1#define BIT7ENV 7 /* 7bit enviornment */#define BIT8ENV 8 /* 8bit environment */#define NUM_OF_STATES 4 /* G0, G1, G2, G3 */#define BIT8(_ch) (_ch & 0x80)#define MAXSIZE 100 /* ESC LOCK upper lower */#define USE_STATE 0 /* use the actual _state info */#define USE_CONTROL 1 /* use C0 or C1 */#define USE_SS2 2 /* use Single shift 2 */#define USE_SS3 3 /* use Single shift 3 */#define G0MASK 0x0000#define G1MASK 0x0080#define G2MASK 0x8000#define G3MASK 0x8080#define FINAL 0x33 /* Temporary final character */#define MMB_CUR_MAX 128/* * Keep state informations */struct state { char width; /* 1 or 2 */ char final; /* final character */};static char _my_env = BIT7ENV; /* default 7bits environment */static struct state Invoked_G0, Invoked_G1;static char _currentG0 = G0;static char _currentG1 = G1;static struct state _des_states[NUM_OF_STATES] = { {-1, 0}, {-1, 0}, {-1, 0}, {01, 0}};int _savestates(); /* save states */int _restorestates(); /* restore states */int _initializestates();/* Initialize states *//* * Variables for wc*tomb*() */static char _currentOUT = G0; /* G0, G1, G2 or G3 */static prevcsize = 1;/* * mbtowc - subroutine for most iso codeset sequences */int_mbtowc_iso(pwc, s, n) wchar_t *pwc; char *s; size_t n;{ unsigned char ch; unsigned char tch; /* temporary use */ unsigned char *us = (unsigned char *)s; int gen_wide_state = USE_STATE; /* used in gen_wide: */ int length = 0; int len = 0; wchar_t wide; int mask; int i; isowidth_t * isoinfo = (isowidth_t *) _code_set_info.code_info; /* * initialize _g0_stuff */ if (_des_states[G0].width == -1) { _des_states[G0].width = isoinfo->g0_len; _des_states[G1].width = isoinfo->g1_len; _des_states[G2].width = isoinfo->g2_len; _des_states[G3].width = isoinfo->g3_len; _my_env = isoinfo->bit_env; Invoked_G0 = _des_states[G0]; Invoked_G1 = _des_states[G1]; } /* * get character and proceed */loop: ch = *us++; if (++length > n) return (-1); /* too long */ switch (ch) { /* get a character */ /* escape sequence or locking shifts */ case ESC: /* escape sequence */ gen_wide_state = USE_STATE; /* used in gen_wide: */ ch = *us++; if (++length > n) return (-1); /* too long */ switch (ch) { /* DESIGNATE */ case 0x24: /* designate */ ch = *us++; if (++length > n) return (-1); /* too long */ switch (ch) { case 0x28: case 0x29: case 0x2A: case 0x2B: case 0x2D: case 0x2E: case 0x2F: tch = ch; /* save this to decide _des_state */ /* Skip intermidiates */ do { ch = *us++; if (++length > n) return (-1); /* too long */ } while (ch >= 0x20 && ch <= 0x2F); if (ch < 0x30) /* ch should be a final character */ return (-1); /* error */ if (tch == 0x28) i = G0; else if (tch == 0x29 || tch == 0x2D) i = G1; else if (tch == 0x2A || tch == 0x2E) i = G2; else /* (tch == 0x2B || tch == 0x2F) */ i = G3; /* updates state info */ _des_states[i].width = TO_MULTI; _des_states[i].final = ch; goto loop; break; default: /* This is an illegal sequence */ return (-1); break; } break; case 0x28: /* designate */ case 0x29: case 0x2A: case 0x2B: case 0x2D: case 0x2E: case 0x2F: tch = ch; /* save this to decide _des_state */ /* Skip intermidiates */ do { ch = *us++; if (++length > n) return (-1); /* too long */ } while (ch >= 0x20 && ch <= 0x2F); if (ch < 0x30) /* ch should be a final character */ return (-1); /* error */ if (tch == 0x28) i = G0; else if (tch == 0x29 || tch == 0x2D) i = G1; else if (tch == 0x2A || tch == 0x2E) i = G2; else /* (tch == 0x2B || tch == 0x2F) */ i = G3; /* updates state info */ _des_states[i].width = TO_SINGLE; _des_states[i].final = ch; goto loop; break; /* LOCKING SHIFTS */ case LS1R: /* locking shift LS1R */; Invoked_G1 = _des_states[G1]; _currentG1 = G1; goto loop; break; case LS2: /* locking shift LS2 */ Invoked_G0 = _des_states[G2]; _currentG0 = G2; goto loop; break; case LS2R: /* locking shift LS2R */ Invoked_G1 = _des_states[G2]; _currentG1 = G2; goto loop; break; case LS3: /* locking shift LS3 */ Invoked_G0 = _des_states[G3]; _currentG0 = G3; goto loop; break; case LS3R: /* locking shift LS3R */ Invoked_G1 = _des_states[G3]; _currentG1 = G3; goto loop; break; /* CONTROL FUNCTIONS */ case 0x21: /* C0 sets */ case 0x22: /* C1 sets */ do { ch = *us++; if (++length > n) return (-1); /* too long */ } while (ch >= 0x20 && ch <= 0x2F); if (ch < 0x30) /* ch should be a final character */ return (-1); /* error */ goto loop; break; /* SINGLE SHIFT for 7bit environment */ case SS2_7B: /* Single shift SS2 for 7bits */ case SS3_7B: /* Single shoft SS3 for 7bits */ if (ch == SS2_7B) gen_wide_state = USE_SS2; else gen_wide_state = USE_SS3; goto loop; break; default: /* should be an error */ return (-1); break; } /* locking shifts */ case LS0: gen_wide_state = USE_STATE; /* used in gen_wide: */ Invoked_G0 = _des_states[G0]; _currentG0 = G0; goto loop; break; case LS1: gen_wide_state = USE_STATE; /* used in gen_wide: */ Invoked_G0 = _des_states[G1]; _currentG0 = G1; goto loop; break; /* Single shift SS3 and SS2 for 8bits */ case SS2_8B: case SS3_8B: if (ch == SS2_8B) gen_wide_state = USE_SS2; else gen_wide_state = USE_SS3; goto loop; break; /* This character is not any special character/ * It does not change any state. * Goto where it generates wide character. */ default: /* * Use this ch to generate pwc. */ if (ch == 0) { /* end of string or 0 */ wide = 0; mask = 0; goto gen_wide; } break; } /* * Generate pwc here. * The information here is * current state and length. If the length is two, you need to * read one more character. */ switch (gen_wide_state) { case USE_STATE: if (BIT8(ch)) { /* 8bit environment ? */ /* current mode is G1 mode */ if (Invoked_G1.width == 2) { tch = *us++; if (++length > n) return (-1); wide = ch; wide = (wide << 8 | tch); } else { wide = ch; } if (_currentG1 == G0) mask = G0MASK; else if (_currentG1 == G1) mask = G1MASK; else if (_currentG1 == G2) mask = G2MASK; else mask = G3MASK; } else { /* current mode is G0 mode */ if (Invoked_G0.width == 2) { tch = *us++; if (++length > n) return (-1); wide = ch; wide = (wide << 8 | tch); } else { wide = ch; } if (_currentG0 == G0) mask = G0MASK; else if (_currentG0 == G1) mask = G1MASK; else if (_currentG0 == G2) mask = G2MASK; else mask = G3MASK; } break; case USE_SS2: if (_des_states[G2].width == 2) { tch = *us++; if (++length > n) return (-1); wide = ch; wide = (wide << 8 | tch); } else { wide = ch; } mask = G2MASK; break; case USE_SS3: if (_des_states[G3].width == 2) { tch = *us++; if (++length > n) return (-1); wide = ch; wide = (wide << 8 | tch); } else { wide = ch; } mask = G3MASK; break; default: /* shoult be internal error */ return (-1); break; }gen_wide: wide &= 0x7F7F; /* strip off the top bit */ wide = wide | mask; if (pwc != NULL) *pwc = wide; return (length);}#define MAXMBSIZE 128/* * mbstowcs() */ size_t_mbstowcs_iso(pwcs, s, n) wchar_t *pwcs; unsigned char *s; size_t n;{ int ret1; int accsum = 0; wchar_t pwc; /* * If pwcs == 0, do nothing. */ if (pwcs == 0) return (0); /* * States things */ _savestates(); _initializestates(); while (accsum < n) { ret1 = _mbtowc_iso (&pwc, s, MAXMBSIZE); if (ret1 < 0) return (-1); /* error */ if (ret1 == 0 || pwc == 0) { if (pwcs == 0) *pwcs = 0; /* * Restore states */ _restorestates(); return (accsum); } s = s + ret1; /* increment the pointer */ *pwcs++ = pwc; ++accsum; } /* * Restore states */ _restorestates(); return (accsum);}/* * wctomb - */int_wctomb_iso(s, pwc) unsigned char *s; wchar_t pwc;{ unsigned char ch; unsigned char tch; /* temporary use */ unsigned char *us = (unsigned char *)s; int gen_wide_state = USE_STATE; /* used in gen_wide: */ int length = 0; int len = 0; wchar_t wide; unsigned short mode; unsigned char buf[MAXSIZE]; unsigned char *bp; int csize, i; int n = MMB_CUR_MAX; isowidth_t * isoinfo = (isowidth_t *) _code_set_info.code_info; /* * If pwc is 0, do this first. */ if (pwc == 0) { if (s != 0) { *s = 0; return (1); } else { return (0); } } mode = pwc & G3MASK; /* The mode of this character */ if (((pwc >> 8) & 0x007f) == 0) csize = 1; else csize = 2; bp = buf; length = 0;#ifdef DDDebug if (_my_env == BIT7ENV) printf ("7b "); else printf ("8b "); printf ("csize = %d, prevcsize = %d, (%x,%x) ",csize, prevcsize, (pwc>>8)&0x00ff, pwc&0x00ff); switch (mode) { case G0MASK: printf ("G0"); break; case G1MASK: printf ("G1"); break; case G2MASK: printf ("G2"); break; case G3MASK: printf ("G3"); break; default: printf ("XXXX"); break; }#endif switch (_my_env) { case BIT7ENV: /* 7 bit environment */ switch (mode) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -