コード例 #1
0
ファイル: istream.c プロジェクト: macks/w3m
Str
StrmyISgets(InputStream stream)
{
    BaseStream base;
    StreamBuffer sb;
    Str s = NULL;
    int i, len;

    if (stream == NULL)
	return '\0';
    base = &stream->base;
    sb = &base->stream;

    while (!base->iseos) {
	if (MUST_BE_UPDATED(base)) {
	    do_update(base);
	}
	else {
	    if (s && Strlastchar(s) == '\r') {
		if (sb->buf[sb->cur] == '\n')
		    Strcat_char(s, (char)sb->buf[sb->cur++]);
		return s;
	    }
	    for (i = sb->cur;
		 i < sb->next && sb->buf[i] != '\n' && sb->buf[i] != '\r';
		 i++) ;
	    if (i < sb->next) {
		len = i - sb->cur + 1;
		if (s == NULL)
		    s = Strnew_size(len + MARGIN_STR_SIZE);
		Strcat_charp_n(s, (char *)&sb->buf[sb->cur], len);
		sb->cur = i + 1;
		if (sb->buf[i] == '\n')
		    return s;
	    }
	    else {
		if (s == NULL)
		    s = Strnew_size(sb->next - sb->cur + MARGIN_STR_SIZE);
		Strcat_charp_n(s, (char *)&sb->buf[sb->cur],
			       sb->next - sb->cur);
		sb->cur = sb->next;
	    }
	}
    }

    if (s == NULL)
	return Strnew();
    return s;
}
コード例 #2
0
ファイル: anchor.c プロジェクト: yujiabe/w3m
char *
getAnchorText(Buffer *buf, AnchorList *al, Anchor *a)
{
    int hseq, i;
    Line *l;
    Str tmp = NULL;
    char *p, *ep;

    if (!a || a->hseq < 0)
	return NULL;
    hseq = a->hseq;
    l = buf->firstLine;
    for (i = 0; i < al->nanchor; i++) {
	a = &al->anchors[i];
	if (a->hseq != hseq)
	    continue;
	for (; l; l = l->next) {
	    if (l->linenumber == a->start.line)
		break;
	}
	if (!l)
	    break;
	p = l->lineBuf + a->start.pos;
	ep = l->lineBuf + a->end.pos;
	for (; p < ep && IS_SPACE(*p); p++) ;
	if (p == ep)
	    continue;
	if (!tmp)
	    tmp = Strnew_size(ep - p);
	else
	    Strcat_char(tmp, ' ');
	Strcat_charp_n(tmp, p, ep - p);
    }
    return tmp ? tmp->ptr : NULL;
}
コード例 #3
0
ファイル: ucs.c プロジェクト: phantasea/w3m
void
wtf_push_ucs(Str os, wc_uint32 ucs, wc_status *st)
{
    wc_ccs ccs;

    if (ucs >= WC_C_LANGUAGE_TAG0 && ucs <= WC_C_CANCEL_TAG) {
	if (! WcOption.use_language_tag)
	    return;
	if (ucs == WC_C_LANGUAGE_TAG)
	    st->tag = Strnew_size(4);
	else if (ucs == WC_C_CANCEL_TAG) {
	    st->tag = NULL;
	    st->ntag = 0;
	}  else if (st->tag && ucs >= WC_C_TAG_SPACE)
	    Strcat_char(st->tag, (char)(ucs & 0x7f));
	return;
    }
    if (st->tag) {
	st->ntag = wc_ucs_put_tag(st->tag->ptr);
	st->tag = NULL;
    }
    if (ucs < 0x80) {
	if (st->ntag)
	    wtf_push(os, WC_CCS_UCS_TAG,  wc_ucs_to_ucs_tag(ucs, st->ntag));
	else
	    Strcat_char(os, (char)ucs);
    } else {
	ccs = wc_ucs_to_ccs(ucs);
	if (st->ntag && ucs <= WC_C_UNICODE_END) {
	    ccs = wc_ccs_ucs_to_ccs_ucs_tag(ccs);
	    ucs = wc_ucs_to_ucs_tag(ucs, st->ntag);
	}
	wtf_push(os, ccs, ucs);
    }
}
コード例 #4
0
ファイル: Str.c プロジェクト: AOSC-Dev/w3m-ng
Str
Strdup(Str s)
{
    Str n = Strnew_size(s->length);
    STR_LENGTH_CHECK(s);
    Strcopy(n, s);
    return n;
}
コード例 #5
0
ファイル: istream.c プロジェクト: macks/w3m
Str
StrISgets(InputStream stream)
{
    BaseStream base;
    StreamBuffer sb;
    Str s = NULL;
    uchar *p;
    int len;

    if (stream == NULL)
	return '\0';
    base = &stream->base;
    sb = &base->stream;

    while (!base->iseos) {
	if (MUST_BE_UPDATED(base)) {
	    do_update(base);
	}
	else {
	    if ((p = memchr(&sb->buf[sb->cur], '\n', sb->next - sb->cur))) {
		len = p - &sb->buf[sb->cur] + 1;
		if (s == NULL)
		    s = Strnew_size(len);
		Strcat_charp_n(s, (char *)&sb->buf[sb->cur], len);
		sb->cur += len;
		return s;
	    }
	    else {
		if (s == NULL)
		    s = Strnew_size(sb->next - sb->cur + MARGIN_STR_SIZE);
		Strcat_charp_n(s, (char *)&sb->buf[sb->cur],
			       sb->next - sb->cur);
		sb->cur = sb->next;
	    }
	}
    }

    if (s == NULL)
	return Strnew();
    return s;
}
コード例 #6
0
ファイル: Str.c プロジェクト: AOSC-Dev/w3m-ng
Str
Strnew_charp_n(char *p, int n)
{
    Str x;

    if (p == NULL)
	return Strnew_size(n);
    x = GC_MALLOC(sizeof(struct _Str));
    x->ptr = GC_MALLOC_ATOMIC(n + 1);
    x->area_size = n + 1;
    x->length = n;
    bcopy((void *)p, (void *)x->ptr, n);
    x->ptr[n] = '\0';
    return x;
}
コード例 #7
0
ファイル: Str.c プロジェクト: AOSC-Dev/w3m-ng
Str
Stralign_right(Str s, int width)
{
    Str n;
    int i;

    STR_LENGTH_CHECK(s);
    if (s->length >= width)
	return Strdup(s);
    n = Strnew_size(width);
    for (i = s->length; i < width; i++)
	Strcat_char(n, ' ');
    Strcat(n, s);
    return n;
}
コード例 #8
0
ファイル: Str.c プロジェクト: AOSC-Dev/w3m-ng
Str
Stralign_center(Str s, int width)
{
    Str n;
    int i, w;

    STR_LENGTH_CHECK(s);
    if (s->length >= width)
	return Strdup(s);
    n = Strnew_size(width);
    w = (width - s->length) / 2;
    for (i = 0; i < w; i++)
	Strcat_char(n, ' ');
    Strcat(n, s);
    for (i = w + s->length; i < width; i++)
	Strcat_char(n, ' ');
    return n;
}
コード例 #9
0
ファイル: viet.c プロジェクト: harrisonteng/dot.config
Str
wc_conv_from_viet(Str is, wc_ces ces)
{
    Str os;
    wc_uchar *sp = (wc_uchar *)is->ptr;
    wc_uchar *ep = sp + is->length;
    wc_uchar *p;
    wc_ccs ccs1 = WcCesInfo[WC_CCS_INDEX(ces)].gset[1].ccs;
    wc_ccs ccs2 = WcCesInfo[WC_CCS_INDEX(ces)].gset[2].ccs;
    wc_uint8 *map = NULL;

    switch (ces) {
    case WC_CES_TCVN_5712:
	map = wc_c0_tcvn57122_map;
	break;
    case WC_CES_VISCII_11:
	map = wc_c0_viscii112_map;
	break;
    case WC_CES_VPS:
	map = wc_c0_vps2_map;
	break;
    }

    wc_create_detect_map(ces, WC_FALSE);
    for (p = sp; p < ep && ! WC_DETECT_MAP[*p]; p++)
	;
    if (p == ep)
	return is;
    os = Strnew_size(is->length);
    if (p > sp)
	Strcat_charp_n(os, is->ptr, (int)(p - sp));

    for (; p < ep; p++) {
	if (*p & 0x80)
	    wtf_push(os, ccs1, (wc_uint32)*p);
	else if (*p < 0x20 && map[*p])
	    wtf_push(os, ccs2, (wc_uint32)*p);
	else
	    Strcat_char(os, (char)*p);
    }
    return os;
}
コード例 #10
0
ファイル: etc.c プロジェクト: harrisonteng/dot.config
Str
checkType(Str s, Lineprop **oprop, Linecolor **ocolor)
{
    Lineprop mode;
    Lineprop effect = PE_NORMAL;
    Lineprop *prop;
    static Lineprop *prop_buffer = NULL;
    static int prop_size = 0;
    char *str = s->ptr, *endp = &s->ptr[s->length], *bs = NULL;
#ifdef USE_ANSI_COLOR
    Lineprop ceffect = PE_NORMAL;
    Linecolor cmode = 0;
    int check_color = FALSE;
    Linecolor *color = NULL;
    static Linecolor *color_buffer = NULL;
    static int color_size = 0;
    char *es = NULL;
#endif
    int do_copy = FALSE;
    int i;
    int plen = 0, clen;

    if (prop_size < s->length) {
	prop_size = (s->length > LINELEN) ? s->length : LINELEN;
	prop_buffer = New_Reuse(Lineprop, prop_buffer, prop_size);
    }
    prop = prop_buffer;

    if (ShowEffect) {
	bs = memchr(str, '\b', s->length);
#ifdef USE_ANSI_COLOR
	if (ocolor) {
	    es = memchr(str, ESC_CODE, s->length);
	    if (es) {
		if (color_size < s->length) {
		    color_size = (s->length > LINELEN) ? s->length : LINELEN;
		    color_buffer = New_Reuse(Linecolor, color_buffer,
					     color_size);
		}
		color = color_buffer;
	    }
	}
#endif
	if ((bs != NULL)
#ifdef USE_ANSI_COLOR
	    || (es != NULL)
#endif
	    ) {
	    char *sp = str, *ep;
	    s = Strnew_size(s->length);
	    do_copy = TRUE;
	    ep = bs ? (bs - 2) : endp;
#ifdef USE_ANSI_COLOR
	    if (es && ep > es - 2)
		ep = es - 2;
#endif
	    for (; str < ep && IS_ASCII(*str); str++) {
		*(prop++) = PE_NORMAL | (IS_CNTRL(*str) ? PC_CTRL : PC_ASCII);
#ifdef USE_ANSI_COLOR
		if (color)
		    *(color++) = 0;
#endif
	    }
	    Strcat_charp_n(s, sp, (int)(str - sp));
	}
    }
    if (!do_copy) {
	for (; str < endp && IS_ASCII(*str); str++)
	    *(prop++) = PE_NORMAL | (IS_CNTRL(*str) ? PC_CTRL : PC_ASCII);
    }

    while (str < endp) {
	if (prop - prop_buffer >= prop_size)
	    break;
	if (bs != NULL) {
#ifdef USE_M17N
	    if (str == bs - 2 && !strncmp(str, "__\b\b", 4)) {
		str += 4;
		effect = PE_UNDER;
		if (str < endp)
		    bs = memchr(str, '\b', endp - str);
		continue;
	    }
	    else
#endif
	    if (str == bs - 1 && *str == '_') {
		str += 2;
		effect = PE_UNDER;
		if (str < endp)
		    bs = memchr(str, '\b', endp - str);
		continue;
	    }
	    else if (str == bs) {
		if (*(str + 1) == '_') {
		    if (s->length) {
			str += 2;
#ifdef USE_M17N
			for (i = 1; i <= plen; i++)
			    *(prop - i) |= PE_UNDER;
#else
			*(prop - 1) |= PE_UNDER;
#endif
		    }
		    else {
			str++;
		    }
		}
#ifdef USE_M17N
		else if (!strncmp(str + 1, "\b__", 3)) {
		    if (s->length) {
			str += (plen == 1) ? 3 : 4;
			for (i = 1; i <= plen; i++)
			    *(prop - i) |= PE_UNDER;
		    }
		    else {
			str += 2;
		    }
		}
		else if (*(str + 1) == '\b') {
		    if (s->length) {
			clen = get_mclen(str + 2);
			if (plen == clen &&
			    !strncmp(str - plen, str + 2, plen)) {
			    for (i = 1; i <= plen; i++)
				*(prop - i) |= PE_BOLD;
			    str += 2 + clen;
			}
			else {
			    Strshrink(s, plen);
			    prop -= plen;
			    str += 2;
			}
		    }
		    else {
			str += 2;
		    }
		}
#endif
		else {
		    if (s->length) {
#ifdef USE_M17N
			clen = get_mclen(str + 1);
			if (plen == clen &&
			    !strncmp(str - plen, str + 1, plen)) {
			    for (i = 1; i <= plen; i++)
				*(prop - i) |= PE_BOLD;
			    str += 1 + clen;
			}
			else {
			    Strshrink(s, plen);
			    prop -= plen;
			    str++;
			}
#else
			if (*(str - 1) == *(str + 1)) {
			    *(prop - 1) |= PE_BOLD;
			    str += 2;
			}
			else {
			    Strshrink(s, 1);
			    prop--;
			    str++;
			}
#endif
		    }
		    else {
			str++;
		    }
		}
		if (str < endp)
		    bs = memchr(str, '\b', endp - str);
		continue;
	    }
#ifdef USE_ANSI_COLOR
	    else if (str > bs)
		bs = memchr(str, '\b', endp - str);
#endif
	}
#ifdef USE_ANSI_COLOR
	if (es != NULL) {
	    if (str == es) {
		int ok = parse_ansi_color(&str, &ceffect, &cmode);
		if (str < endp)
		    es = memchr(str, ESC_CODE, endp - str);
		if (ok) {
		    if (cmode)
			check_color = TRUE;
		    continue;
		}
	    }
	    else if (str > es)
		es = memchr(str, ESC_CODE, endp - str);
	}
#endif

	plen = get_mclen(str);
	mode = get_mctype(str) | effect;
#ifdef USE_ANSI_COLOR
	if (color) {
	    *(color++) = cmode;
	    mode |= ceffect;
	}
#endif
	*(prop++) = mode;
#ifdef USE_M17N
	if (plen > 1) {
	    mode = (mode & ~PC_WCHAR1) | PC_WCHAR2;
	    for (i = 1; i < plen; i++) {
		*(prop++) = mode;
#ifdef USE_ANSI_COLOR
		if (color)
		    *(color++) = cmode;
#endif
	    }
	    if (do_copy)
		Strcat_charp_n(s, (char *)str, plen);
	    str += plen;
	}
	else
#endif
	{
	    if (do_copy)
		Strcat_char(s, (char)*str);
	    str++;
	}
	effect = PE_NORMAL;
    }
    *oprop = prop_buffer;
#ifdef USE_ANSI_COLOR
    if (ocolor)
	*ocolor = check_color ? color_buffer : NULL;
#endif
    return s;
}
コード例 #11
0
ファイル: gb18030.c プロジェクト: AOSC-Dev/w3m-ng
Str
wc_char_conv_from_gb18030(wc_uchar c, wc_status *st)
{
    static Str os;
    static wc_uchar gb[4];
    wc_uint32 gbk;
    wc_wchar_t cc;
#ifdef USE_UNICODE
    wc_uint32 ucs;
#endif

    if (st->state == -1) {
	st->state = WC_GB18030_NOSTATE;
	os = Strnew_size(8);
    }

    switch (st->state) {
    case WC_GB18030_NOSTATE:
	switch (WC_GB18030_MAP[c]) {
	case UB:
	    gb[0] = c;
	    st->state = WC_GB18030_MBYTE1;
	    return NULL;
	case C1:
	    break;
	default:
	    Strcat_char(os, (char)c);
	    break;
	}
	break;
    case WC_GB18030_MBYTE1:
	if (WC_GB18030_MAP[c] & LB) {
	    gbk = ((wc_uint32)gb[0] << 8) | c;
	    if (wc_gbk_or_gbk_ext(gbk) == WC_CCS_GBK_EXT)
		wtf_push(os, WC_CCS_GBK_EXT, gbk);
	    else if (gb[0] >= 0xA1 && c >= 0xA1)
		wtf_push(os, wc_gb2312_or_gbk(gbk), gbk);
	    else
		wtf_push(os, WC_CCS_GBK, gbk);
	} else if (WC_GB18030_MAP[c] == L4) {
	    gb[1] = c;
	    st->state = WC_GB18030_MBYTE2;
	    return NULL;
	}
	break;
    case WC_GB18030_MBYTE2:
	if (WC_GB18030_MAP[c] == UB) {
	    gb[2] = c;
	    st->state = WC_GB18030_MBYTE3;
	    return NULL;
	}
	break;
    case WC_GB18030_MBYTE3:
	if (WC_GB18030_MAP[c] == L4) {
	    cc.ccs = WC_CCS_GB18030_W;
	    cc.code = ((wc_uint32)gb[0] << 24)
		    | ((wc_uint32)gb[1] << 16)
		    | ((wc_uint32)gb[2] << 8)
		    | c;
#ifdef USE_UNICODE
	    if (WcOption.gb18030_as_ucs &&
		(ucs = wc_gb18030_to_ucs(cc)) != WC_C_UCS4_ERROR)
		wtf_push(os, WC_CCS_GB18030 | (wc_ucs_to_ccs(ucs) & ~WC_CCS_A_SET), cc.code);
	    else
#endif
	        wtf_push(os, cc.ccs, cc.code);
	}
	break;
    }
    st->state = -1;
    return os;
}
コード例 #12
0
ファイル: gb18030.c プロジェクト: AOSC-Dev/w3m-ng
Str
wc_conv_from_gb18030(Str is, wc_ces ces)
{
    Str os;
    wc_uchar *sp = (wc_uchar *)is->ptr;
    wc_uchar *ep = sp + is->length;
    wc_uchar *p;
    int state = WC_GB18030_NOSTATE;
    wc_uint32 gbk;
    wc_wchar_t cc;
#ifdef USE_UNICODE
    wc_uint32 ucs;
#endif

    for (p = sp; p < ep && *p < 0x80; p++) 
	;
    if (p == ep)
	return is;
    os = Strnew_size(is->length);
    if (p > sp)
	Strcat_charp_n(os, (char *)is->ptr, (int)(p - sp));

    for (; p < ep; p++) {
	switch (state) {
	case WC_GB18030_NOSTATE:
	    switch (WC_GB18030_MAP[*p]) {
	    case UB:
		state = WC_GB18030_MBYTE1;
		break;
	    case C1:
		wtf_push_unknown(os, p, 1);
		break;
	    default:
		Strcat_char(os, (char)*p);
		break;
	    }
	    break;
	case WC_GB18030_MBYTE1:
	    if (WC_GB18030_MAP[*p] & LB) {
		gbk = ((wc_uint32)*(p-1) << 8) | *p;
		if (wc_gbk_or_gbk_ext(gbk) == WC_CCS_GBK_EXT)
		    wtf_push(os, WC_CCS_GBK_EXT, gbk);
		else if (*(p-1) >= 0xA1 && *p >= 0xA1)
		    wtf_push(os, wc_gb2312_or_gbk(gbk), gbk);
		else
		    wtf_push(os, WC_CCS_GBK, gbk);
	    } else if (WC_GB18030_MAP[*p] == L4) {
		state = WC_GB18030_MBYTE2;
		break;
	    } else
		wtf_push_unknown(os, p-1, 2);
	    state = WC_GB18030_NOSTATE;
	    break;
	case WC_GB18030_MBYTE2:
	    if (WC_GB18030_MAP[*p] == UB) {
		state = WC_GB18030_MBYTE3;
		break;
	    } else
		wtf_push_unknown(os, p-2, 3);
	    state = WC_GB18030_NOSTATE;
	    break;
	case WC_GB18030_MBYTE3:
	    if (WC_GB18030_MAP[*p] == L4) {
		cc.ccs = WC_CCS_GB18030_W;
		cc.code = ((wc_uint32)*(p-3) << 24)
		        | ((wc_uint32)*(p-2) << 16)
		        | ((wc_uint32)*(p-1) << 8)
		        | *p;
#ifdef USE_UNICODE
		if (WcOption.gb18030_as_ucs &&
		    (ucs = wc_gb18030_to_ucs(cc)) != WC_C_UCS4_ERROR)
		    wtf_push(os, WC_CCS_GB18030 | (wc_ucs_to_ccs(ucs) & ~WC_CCS_A_SET), cc.code);
		else
#endif
		    wtf_push(os, cc.ccs, cc.code);
	    } else
		wtf_push_unknown(os, p-3, 4);
	    state = WC_GB18030_NOSTATE;
	    break;
	}
    }
    switch (state) {
    case WC_GB18030_MBYTE1:
	wtf_push_unknown(os, p-1, 1);
	break;
    case WC_GB18030_MBYTE2:
	wtf_push_unknown(os, p-2, 2);
	break;
    case WC_GB18030_MBYTE3:
	wtf_push_unknown(os, p-3, 3);
	break;
    }
    return os;
}
コード例 #13
0
ファイル: conv.c プロジェクト: harrisonteng/dot.config
static Str
wc_conv_to_ces(Str is, wc_ces ces)
{
    Str os;
    wc_uchar *sp = (wc_uchar *)is->ptr;
    wc_uchar *ep = sp + is->length;
    wc_uchar *p;
    wc_status st;

    switch (ces) {
    case WC_CES_HZ_GB_2312:
	for (p = sp; p < ep && *p != '~' && *p < 0x80; p++)
	    ;
	break;
    case WC_CES_TCVN_5712:
    case WC_CES_VISCII_11:
    case WC_CES_VPS:
	for (p = sp; p < ep && 0x20 <= *p && *p < 0x80; p++)
	    ;
	break;
    default:
	for (p = sp; p < ep && *p < 0x80; p++)
	    ;
	break;
    }
    if (p == ep)
	return is;

    os = Strnew_size(is->length);
    if (p > sp)
	p--;	/* for precompose */
    if (p > sp)
	Strcat_charp_n(os, is->ptr, (int)(p - sp));

    wc_output_init(ces, &st);

    switch (ces) {
    case WC_CES_ISO_2022_JP:
    case WC_CES_ISO_2022_JP_2:
    case WC_CES_ISO_2022_JP_3:
    case WC_CES_ISO_2022_CN:
    case WC_CES_ISO_2022_KR:
    case WC_CES_HZ_GB_2312:
    case WC_CES_TCVN_5712:
    case WC_CES_VISCII_11:
    case WC_CES_VPS:
#ifdef USE_UNICODE
    case WC_CES_UTF_8:
    case WC_CES_UTF_7:
#endif
	while (p < ep)
	    (*st.ces_info->push_to)(os, wtf_parse(&p), &st);
	break;
    default:
	while (p < ep) {
	    if (*p < 0x80 && wtf_width(p + 1)) {
		Strcat_char(os, (char)*p);
		p++;
	    } else
		(*st.ces_info->push_to)(os, wtf_parse(&p), &st);
	}
	break;
    }

    wc_push_end(os, &st);

    return os;
}
コード例 #14
0
Str wc_conv_from_hz( Str is, wc_ces ces )
{
  int eax;
  Str os;
  wc_uchar *sp = (wc_uchar*)is->ptr;
  wc_uchar *ep = &sp[ is->length ];
  wc_uchar *p;
  int state = 0;
  p = sp;
  if ( p < ep )
  {
    if ( p[0] >= 0 )
    {
      if ( p[0] != '~' )
        p++;
      else
      {
        if ( p == ep )
        {
          is->ptr = (char*)is;
          return os;
        }
        else
        {
          os = Strnew_size( is->length );
          if ( sp < p )
            Strcat_charp_n( os, is->ptr, p - sp );
            p++;
            if ( p < ep )
            {
              switch ( state )
              {
              default:
                break;
              case 0:
                if ( p[0] == '~' )
                  state = 1;
                else
                {
                  if ( WC_ISO_MAP[ p[0] ] == '@' )
                    state = 5;
                  else
                  {
                    if ( p[0] < 0 )
                    {
                      wtf_push_unknown( os, p, 1 );
                    }
                    if ( os->area_size <= os->length + 1 )
                      Strgrow( os );
                      os->ptr[ os->length ] = p[0];
                      os->length++;
                      os->ptr[ os->length ] = 0;
                    else
                    {
                      os->ptr[ os->length ] = p[0];
                      os->length++;
                      os->ptr[ os->length ] = 0;
                    }
                  }
                }
                break;
              case 1:
                if ( p[0] == '{' )
                  state = 3;
                else
                {
                  if ( p[0] == '~' )
                  {
                    if ( os->area_size <= os->length + 1 )
                      Strgrow( os );
                      os->ptr[ os->length ] = p[0];
                      os->length++;
                      os->ptr[ os->length ] = 0;
                      state = 0;
                    else
                    {
                      os->ptr[ os->length ] = p[0];
                      os->length++;
                      os->ptr[ os->length ] = 0;
                      state = 0;
                    }
                  }
                  else
                  {
                    if ( p[0] == 10 )
                    {
                    }
                    else
                      wtf_push_unknown( os, &p[ -1 ], 2 );
                      state = 0;
                  }
                }
                break;
              case 2:
                if ( p[0] != '}' )
                {
                  if ( p[0] == 10 )
                    state = 0;
                  else
                  {
                    if ( ( WC_ISO_MAP[ p[0] & 127 ] & 255 ) == 0 )
                    {
                      wtf_push( os, 33089, p[0] | ( p[ -1 ] << 8 ) );
                    }
                    wtf_push_unknown( os, &p[ -1 ], 2 );
                    state = 3;
                  }
                }
                else
                  state = 0;
                break;
              case 3:
                if ( p[0] == '~' )
                  state = 2;
                else
                {
                  if ( ( WC_ISO_MAP[ p[0] & 127 ] & 255 ) == 0 )
                    state = 4;
                  else
                    wtf_push_unknown( os, p, 1 );
                }
                break;
              case 4:
                if ( ( WC_ISO_MAP[ p[0] & 127 ] & 255 ) == 0 )
                {
                  wtf_push( os, 33089, p[0] | ( p[ -1 ] << 8 ) );
                }
                wtf_push_unknown( os, &p[ -1 ], 2 );
                state = 3;
                break;
              case 5:
                if ( WC_ISO_MAP[ p[0] ] == '@' )
                {
                  wtf_push( os, 33089, p[0] | ( p[ -1 ] << 8 ) );
                }
                wtf_push_unknown( os, &p[ -1 ], 2 );
                state = 0;
                break;
              }
            }
            else
            {
              if ( state <= 5 )
              {
                if ( ( ( 1 << state ) & 54 ) != 0 )
                  wtf_push_unknown( os, &p[ -1 ], 1 );
                  os->ptr = (char*)os;
                  return os;
              }
            }
          else
          {
          }
        }
      }
    }
  }
}