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; }
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; }
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); } }
Str Strdup(Str s) { Str n = Strnew_size(s->length); STR_LENGTH_CHECK(s); Strcopy(n, s); return n; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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 { } } } } } }