/* * Export options into a string. */ const char *OptString (const Opt *opts) { static str_s str; int i, flag; val_t val = 0; s_init (&str, "", 100); for (i = 0; OptList[i].name; i++) if (OptGetVal (opts, flag = OptList[i].flag, &val)) { if (flag & COF_BOOL) { if (!*str.txt) s_cat (&str, "options"); s_catf (&str, " %s %s", OptList[i].name, val ? "on" : "off"); } else { if (*str.txt) s_catc (&str, '\n'); if (flag & COF_NUMERIC) s_catf (&str, "options %s %lu", OptList[i].name, UD2UL (val)); else if (flag & COF_COLOR) s_catf (&str, "options %s %s", OptList[i].name, s_quote (OptS2C (strtable[val]))); else s_catf (&str, "options %s %s", OptList[i].name, s_quote (strtable[val])); } } if (*str.txt) s_catc (&str, '\n'); return str.txt; }
/* * Insert a character by unicode codepoint, display string in local encoding * and its length, and its width in columns */ static void rl_insert_basic (wchar_tt ucs, const char *display, UDWORD len, UDWORD collen) { int i; if (((rl_prompt_len + rl_colpos) % rl_columns) + collen > rl_columns) { for (i = (rl_columns - ((rl_prompt_len + rl_colpos) % rl_columns)); i > 0; i--) { wint_tt weof = WEOF; s_insn (&rl_ucs, sizeof (wint_tt) * rl_ucspos, (const char *)&weof, sizeof (wint_tt)); s_insc (&rl_ucscol, rl_ucspos, 1); s_insc (&rl_ucsbytes, rl_ucspos++, 1); s_insc (&rl_display, rl_bytepos++, ' '); s_catc (&rl_operate, ' '); rl_colpos++; } } s_insn (&rl_ucs, sizeof (wint_tt) * rl_ucspos, (const char *)&ucs, sizeof (wint_tt)); s_insc (&rl_ucscol, rl_ucspos, collen); s_insc (&rl_ucsbytes, rl_ucspos++, len); s_insn (&rl_display, rl_bytepos, display, len); rl_colpos += collen; rl_bytepos += len; s_cat (&rl_operate, display); }
/* * Go to given column */ static void rl_goto (UDWORD pos) { if (pos == rl_colpos) return; if (rl_colpos > pos) { #ifdef ANSI_TERM int l = ((rl_prompt_len + rl_colpos) / rl_columns) - ((rl_prompt_len + pos) / rl_columns); if (l) s_catf (&rl_operate, ESC "[%dA", l); rl_colpos -= l * rl_columns; s_catc (&rl_operate, '\r'); rl_colpos -= (rl_prompt_len + rl_colpos) % rl_columns; if ((int)rl_colpos < 0) { if (rl_prompt_len) s_catf (&rl_operate, ESC "[%uC", rl_prompt_len); rl_colpos = 0; } #else while (pos < rl_colpos) { s_catc (&rl_operate, '\b'); rl_curpos --; } #endif } rl_syncpos (rl_colpos); while (rl_colpos + rl_ucscol.txt[rl_ucspos] <= pos && rl_ucspos < rl_ucscol.len) { s_catn (&rl_operate, rl_display.txt + rl_bytepos, rl_ucsbytes.txt[rl_ucspos]); rl_colpos += rl_ucscol.txt[rl_ucspos]; rl_bytepos += rl_ucsbytes.txt[rl_ucspos]; rl_ucspos++; } if (!((rl_prompt_len + rl_colpos) % rl_columns)) { if (rl_ucspos < rl_ucscol.len) s_catn (&rl_operate, rl_display.txt + rl_bytepos, rl_ucsbytes.txt[rl_ucspos]); else s_catc (&rl_operate, ' '); s_catc (&rl_operate, '\r'); } assert (rl_colpos == pos); }
/* * Sets the prompt */ void ReadLinePromptSet (const char *prompt) { rl_prompt_time = time (NULL); s_init (&rl_prompt, COLSERVER, 0); s_cat (&rl_prompt, ConvTo (prompt, ENC(enc_loc))->txt); s_cat (&rl_prompt, COLNONE); s_catc (&rl_prompt, ' '); if (rl_prompt_stat != 0) rl_prompt_stat = 2; }
/* * Re-check remaining line for multicolumn line break problems */ static void rl_recheck (BOOL clear) { int gpos, i; gpos = rl_colpos; while (rl_ucspos < rl_ucscol.len) { if (rl_ucs_at (&rl_ucs, rl_ucspos) == WEOF) { s_deln (&rl_ucs, sizeof (wint_tt) * rl_ucspos, sizeof (wint_tt)); s_delc (&rl_ucsbytes, rl_ucspos); s_delc (&rl_ucscol, rl_ucspos); s_delc (&rl_display, rl_bytepos); } else if (((rl_prompt_len + rl_colpos) % rl_columns) + (UBYTE)rl_ucscol.txt[rl_ucspos] > rl_columns) { for (i = (rl_columns - ((rl_prompt_len + rl_colpos) % rl_columns)); i > 0; i--) { wint_tt weof = WEOF; s_insn (&rl_ucs, sizeof (wint_tt) * rl_ucspos, (const char *)&weof, sizeof (wint_tt)); s_insc (&rl_ucscol, rl_ucspos, 1); s_insc (&rl_ucsbytes, rl_ucspos++, 1); s_insc (&rl_display, rl_bytepos++, ' '); s_catc (&rl_operate, ' '); rl_colpos++; } } else { s_catn (&rl_operate, rl_display.txt + rl_bytepos, rl_ucsbytes.txt[rl_ucspos]); rl_bytepos += rl_ucsbytes.txt[rl_ucspos]; rl_colpos += rl_ucscol.txt[rl_ucspos]; rl_ucspos++; } } #ifdef ANSI_TERM s_cat (&rl_operate, " \b"); if (clear) s_cat (&rl_operate, ANSI_CLEAR); #else s_cat (&rl_operate, " \b\b\b\b\b"); #endif rl_goto (gpos); }
/* * Hides the prompt */ void ReadLinePromptHide () { int pos = rl_colpos; ReadLineHandleSig (); if (rl_prompt_stat == 0) return; s_init (&rl_operate, "", 0); rl_goto (0); s_catc (&rl_operate, '\r'); #ifdef ANSI_TERM s_cat (&rl_operate, ANSI_CLEAR); #endif printf ("%s", rl_operate.txt); rl_prompt_stat = 0; rl_colpos = pos; rl_print ("\r"); }
/* * Shows the prompt */ void ReadLinePrompt () { int gpos = rl_colpos; if (rl_prompt_stat == 1) return; #if DEBUG_RL fprintf (stderr, "killoper: %s\n", s_qquote (rl_operate.txt)); #endif s_init (&rl_operate, "", 0); if (rl_prompt_stat == 2) rl_goto (0); if (rl_prompt_stat == 2) { s_catc (&rl_operate, '\r'); #ifdef ANSI_TERM s_cat (&rl_operate, ANSI_CLEAR); #endif rl_prompt_stat = 0; } #if DEBUG_RL fprintf (stderr, "oper(rm): %s\n", s_qquote (rl_operate.txt)); #endif printf ("%s", rl_operate.txt); if (rl_prompt_stat == 0) { rl_print ("\r"); rl_print (rl_prompt.txt); rl_prompt_len = rl_pos (); rl_prompt_stat = 1; rl_colpos = 0; } s_init (&rl_operate, "", 0); rl_recheck (TRUE); rl_goto (gpos); printf ("%s", rl_operate.txt); }
int main(int argc, char **argv) { int i; HC_DEF_S(s); HC_DEF_S(repr); /* */ for (i=1; i<=100; i++) { s_catc(s, i); } s_repr(repr, s); print_s("[", repr, "]\n"); assert(s_diffz(s, "\x01\x02\x03\x04\x05\x06\x07\x08\t\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcd") == 0); /* */ repr->len = 0; s_reprz(repr, "\x1\x2\x3"); print_s("[", repr, "]\n"); assert(s_diffz(repr, "\\x01\\x02\\x03") == 0); /* */ s_free(repr); s_free(s); return 0; }
int main(int argc, char **argv) { HC_DEF_S(s); s_catz(s, "hello world of possibilities!"); HC_SAFE_CSTR(s); fprintf(stdout, "[%i][%i][%s]\n", s->len, s->a, s->s); s->len = 0; /* truncate string */ s_catn(s, "hi ", 3); fwrite(s->s, s->len, 1, stdout); s_copyc(s, 'f'); s_catz(s, "olk"); s_catc(s, 's'); s_catc(s, '!'); s_catc(s, '\n'); fwrite(s->s, s->len, 1, stdout); s_upper(s); fwrite(s->s, s->len, 1, stdout); s_lower(s); fwrite(s->s, s->len, 1, stdout); s_copyz(s, "aa"); assert(sdiff("aa", "aa") == 0); assert(s_diffz(s, "aa") == 0); assert(s_diffn(s, "aa", slen("aa")) == 0); assert(sdiff("aa", "aaz") < 0); assert(s_diffz(s, "aaz") < 0); assert(s_diffn(s, "aaz", slen("aaz")) < 0); assert(sdiff("aa", "a0z") > 0); assert(s_diffz(s, "a0z") > 0); assert(s_diffn(s, "a0z", slen("a0z")) > 0); assert(sdiff("aa", "0") > 0); assert(s_diffz(s, "0") > 0); assert(s_diffn(s, "0", slen("0")) > 0); assert(sdiff("aa", "0zz") > 0); assert(s_diffz(s, "0zz") > 0); assert(s_diffn(s, "0zz", slen("0zz")) > 0); assert(sdiff("aa", "a") > 0); assert(s_diffz(s, "a") > 0); assert(s_diffn(s, "a", slen("a")) > 0); assert(sdiff("aa", "a0") > 0); assert(s_diffz(s, "a0") > 0); assert(s_diffn(s, "a0", slen("a0")) > 0); s_free(s); /* */ assert(s_cat_u4_hex(s, 0) == 1); assert(s_diffz(s, "0") == 0); print_s("[", s, "]\n"); s->len = 0; assert(s_cat_i4_hex(s, 0) == 1); assert(s_diffz(s, "0") == 0); print_s("[", s, "]\n"); s->len = 0; assert(s_cat_u4_hex(s, 0xffffffff) == 8); assert(s_diffz(s, "ffffffff") == 0); print_s("[", s, "]\n"); s->len = 0; assert(s_cat_i4_hex(s, (int32_t)0xffffffff) == 2); assert(s_diffz(s, "-1") == 0); print_s("[", s, "]\n"); s_free(s); /* */ assert(s_cat_u4_dec(s, 0) == 1); assert(s_diffz(s, "0") == 0); print_s("[", s, "]\n"); s->len = 0; assert(s_cat_i4_dec(s, 0) == 1); assert(s_diffz(s, "0") == 0); print_s("[", s, "]\n"); s->len = 0; assert(s_cat_u4_dec(s, 0xffffffff) == 10); assert(s_diffz(s, "4294967295") == 0); print_s("[", s, "]\n"); s->len = 0; assert(s_cat_i4_dec(s, (int32_t)0xffffffff) == 2); assert(s_diffz(s, "-1") == 0); print_s("[", s, "]\n"); s_free(s); /* */ assert(s_cat_u4_base36(s, 0) == 1); assert(s_diffz(s, "0") == 0); print_s("[", s, "]\n"); s->len = 0; assert(s_cat_i4_base36(s, 0) == 1); assert(s_diffz(s, "0") == 0); print_s("[", s, "]\n"); s->len = 0; assert(s_cat_u4_base36(s, 0xffffffff) == 7); assert(s_diffz(s, "1z141z3") == 0); print_s("[", s, "]\n"); s->len = 0; assert(s_cat_i4_base36(s, (int32_t)0xffffffff) == 2); assert(s_diffz(s, "-1") == 0); print_s("[", s, "]\n"); s_free(s); /* */ { void *out; int putlen; HC_DEF_S(t); s_copyz(s, "hello world of possibilities!"); putlen = s_putlen(s); HC_ALLOC(out, putlen); assert(s_put(s, out) == putlen); assert(s_get(t, out) == putlen); assert(s_diff(s, t) == 0); s->len = 0; s_reprn(s, out, putlen); print_s("[", s, "]\n"); HC_FREE(out); s_free(t); } /* */ s_free(s); return 0; }
/* * Process one byte of input */ str_t ReadLine (UBYTE newbyte) { strc_t input, inputucs; static UWORD ucsesc; UWORD ucs; ReadLineHandleSig (); s_catc (&rl_input, newbyte); input = ConvFrom (&rl_input, prG->enc_loc); if (input->txt[0] == CHAR_INCOMPLETE) { if (strcmp (rl_input.txt, ConvTo (input->txt, prG->enc_loc)->txt)) return NULL; } rl_inputdone = 0; rl_signal &= ~1; inputucs = ConvTo (input->txt, ENC_UCS2BE); ucs = ((UBYTE)inputucs->txt[1]) | (((UBYTE)inputucs->txt[0]) << 8); s_init (&rl_input, "", 0); s_init (&rl_operate, "", 0); rl_dump_line (); ReadLinePrompt (); switch (rl_stat) { case 0: if (0) ; #if HAVE_TCGETATTR #if defined(VERASE) else if (ucs == tty_attr.c_cc[VERASE] && tty_attr.c_cc[VERASE] != _POSIX_VDISABLE) rl_key_backspace (); #endif #if defined(VEOF) else if (ucs == tty_attr.c_cc[VEOF] && tty_attr.c_cc[VEOF] != _POSIX_VDISABLE) { rl_tab_cancel (); if (rl_ucscol.len) { rl_key_left (); rl_key_delete (); } else { rl_insert ('q'); rl_historyadd (); } } #endif #if defined(VKILL) else if (ucs == tty_attr.c_cc[VKILL] && tty_attr.c_cc[VKILL] != _POSIX_VDISABLE) rl_key_kill (); #endif #if defined(VREPRINT) else if (ucs == tty_attr.c_cc[VREPRINT] && tty_attr.c_cc[VREPRINT] != _POSIX_VDISABLE) ReadLinePromptHide (); #endif #endif else switch (ucs) { case 1: /* ^A */ rl_tab_cancel (); rl_goto (0); break; case 5: /* ^E */ rl_key_end (); break; case 8: /* ^H = \b */ rl_key_backspace (); break; case 9: /* ^I = \t */ rl_key_tab (); break; case 11: /* ^K */ rl_key_cut (); break; case 12: /* ^L */ ReadLineClrScr (); break; case '\r': case '\n': rl_tab_accept (); if (rl_tab_state == 0) rl_checkautoexpand (); rl_key_end (); rl_historyadd (); break; case 23: /* ^W */ rl_key_delete_backward_word (); break; case 25: /* ^Y */ if (rl_yank) { rl_tab_state = 0; rl_goto (0); rl_lineexpand (rl_yank); } break; case 27: /* ^[ = ESC */ #ifdef ANSI_TERM rl_stat = 1; #endif break; case 32: /* = SPACE */ if (rl_tab_state > 0) rl_tab_accept (); else if (rl_tab_state == 0) rl_checkautoexpand (); rl_insert (' '); break; case 127: /* DEL */ if (prG->flags & FLAG_DELBS) rl_key_backspace (); else rl_key_delete (); break; case 0x9b: /* CSI */ #ifdef ANSI_TERM if (ENC(enc_loc) == ENC_LATIN1) { rl_stat = 2; break; } #else printf ("\a"); break; #endif /* fall-through */ default: rl_key_insert (ucs); } break; #ifdef ANSI_TERM case 1: /* state 1: ESC was pressed */ rl_stat = 0; if (ucs == 'u' || ucs == 'U') rl_stat = 10; else if (ucs == '[' || ucs == 'O') rl_stat = 2; else if (ucs == 'b') rl_key_backward_word (); else if (ucs == 'f') rl_key_forward_word (); else if (ucs == 127) rl_key_delete_backward_word (); else printf ("\a"); break; case 2: /* state 2: CSI was typed */ rl_stat = 0; switch (ucs) { case 'A': /* up */ rl_tab_cancel (); rl_historyback (); break; case 'B': /* down */ rl_tab_cancel (); rl_historyforward (); break; case 'C': /* right */ rl_key_right (); break; case 'D': /* left */ rl_key_left (); break; case 'H': /* home */ rl_tab_cancel (); rl_goto (0); break; case 'F': /* end */ rl_key_end (); break; case 'Z': /* shift tab */ rl_key_shifttab (); break; case '3': /* + ~ = delete */ rl_stat = 3; break; case '1': /* + ~ = home */ case '7': /* + ~ = home */ rl_stat = 4; break; case '4': /* + ~ = end */ case '8': /* + ~ = end */ rl_stat = 5; break; default: printf ("\a"); } break; case 3: /* state 3: incomplete delete key */ rl_stat = 0; if (ucs == '~') rl_key_delete (); else printf ("\a"); break; case 4: /* state 4: incomplete home key */ rl_stat = 0; if (ucs == '~') { rl_tab_cancel (); rl_goto (0); } else printf ("\a"); break; case 5: /* state 5: incomplete end key */ rl_stat = 0; if (ucs == '~') rl_key_end (); else printf ("\a"); break; case 10: /* state 10: unicode sequence to be entered */ rl_stat++; if (ucs >= '0' && ucs <= '9') ucsesc = ucs - '0'; else if (ucs >= 'a' && ucs <= 'f') ucsesc = ucs - 'a' + 10; else if (ucs >= 'A' && ucs <= 'F') ucsesc = ucs - 'A' + 10; else { rl_stat = 0; printf ("\a"); } break; case 11: rl_stat++; ucsesc <<= 4; if (ucs >= '0' && ucs <= '9') ucsesc |= ucs - '0'; else if (ucs >= 'a' && ucs <= 'f') ucsesc |= ucs - 'a' + 10; else if (ucs >= 'A' && ucs <= 'F') ucsesc |= ucs - 'A' + 10; else { rl_stat = 0; printf ("\a"); } break; case 12: rl_stat++; ucsesc <<= 4; if (ucs >= '0' && ucs <= '9') ucsesc |= ucs - '0'; else if (ucs >= 'a' && ucs <= 'f') ucsesc |= ucs - 'a' + 10; else if (ucs >= 'A' && ucs <= 'F') ucsesc |= ucs - 'A' + 10; else { rl_stat = 0; printf ("\a"); } break; case 13: rl_stat = 0; ucsesc <<= 4; if (ucs >= '0' && ucs <= '9') ucsesc |= ucs - '0'; else if (ucs >= 'a' && ucs <= 'f') ucsesc |= ucs - 'a' + 10; else if (ucs >= 'A' && ucs <= 'F') ucsesc |= ucs - 'A' + 10; else { printf ("\a"); break; } rl_key_insert (ucsesc); break; } #endif #if DEBUG_RL fprintf (stderr, "oper: %s\n", s_qquote (rl_operate.txt)); #endif rl_dump_line (); if (rl_operate.len) printf ("%s", rl_operate.txt); if (!rl_inputdone) return NULL; printf ("\n"); return &rl_temp; }