/** * Returns a newly allocated string */ static char * json_parse_string(const char *start, const char **endp, const char **failp, const char **failmsg) { const char *s; while(*start > 0 && *start < 33) start++; if(*start != '"') return NOT_THIS_TYPE; start++; int len = 0; for(s = start; *s != '"';) { int v = json_str_read_char(&s); if(v == -1) { *failmsg = "Unexpected end of JSON message"; *failp = s; return NULL; } if(v == -2) { *failmsg = "Incorrect escape sequence"; *failp = s; return NULL; } len += utf8_put(NULL, v); } char *r = malloc(len + 1); char *dst = r; r[len] = 0; for(s = start; *s != '"';) { int v = json_str_read_char(&s); assert(v > 0); dst += utf8_put(dst, v); } *endp = s + 1; return r; }
int big5_convert(const struct charset *cs, char *dst, const char *src, int len, int strict) { int outlen = 0; for(int i = 0; i < len; i++) { if(*src < 0x80) { if(dst != NULL) *dst++ = *src; outlen++; src++; continue; } unsigned int in; if(len == 1) { in = -1; src++; } else { in = (src[0] << 8) | src[1]; in -= BIG5_TABLE_OFFSET; src += 2; i++; } uint16_t out; if(in > sizeof(big5table) / 2) { if(strict) return -1; out = 0xfffd; } else { out = big5table[in]; if(out == 0) { if(strict) return -1; else out = 0xfffd; } } int ol = utf8_put(dst, out); outlen += ol; if(dst) dst += ol; } return outlen; }
static void updatestr(glw_keyintercept_t *ki) { char str[KI_BUF_LEN * 5 + 1]; char *q; int i; q = str; for(i = 0; i < ki->buflen - 6; i++) q += utf8_put(q, ki->buf[i]); *q = 0; if(ki->prop != NULL) prop_set_string_ex(ki->prop, ki->sub, str, PROP_STR_UTF8); }
/*---------------------------------------------------------------------- Read a character from keyboard with timeout Input: none Result: Returns command read via read_char Times out and returns a null command every so often Calculates the timeout for the read, and does a few other house keeping things. The duration of the timeout is set in pine.c. ----------------------------------------------------------------------*/ UCS read_command(char **utf8str) { int tm = 0, more_freq_timeo; UCS ucs; long dtime; static unsigned char utf8buf[7]; unsigned char *newdestp; /* * timeo is the mail-check-interval. What we want to do (ignoring the * messages_queued part) is timeout more often than timeo but only * check for new mail every timeo or so seconds. The reason we want to * timeout more often is so that we will have a chance to catch the user * in an idle period where we can do a check_point(). Otherwise, with * a default mail-check-interval, we are almost always calling newmail * right after the user presses a key, making it the worst possible * time to do a checkpoint. */ more_freq_timeo = MIN(get_input_timeout(), IDLE_TIMEOUT); if(more_freq_timeo == 0) more_freq_timeo = IDLE_TIMEOUT; cancel_busy_cue(-1); tm = (messages_queued(&dtime) > 1) ? (int)dtime : more_freq_timeo; if(utf8str) *utf8str = NULL; ucs = read_char(tm); if(ucs != NO_OP_COMMAND && ucs != NO_OP_IDLE && ucs != KEY_RESIZE) zero_new_mail_count(); #ifdef BACKGROUND_POST /* * Any expired children to report on? */ if(ps_global->post && ps_global->post->pid == 0){ int winner = 0; if(ps_global->post->status < 0){ q_status_message(SM_ORDER | SM_DING, 3, 3, "Abysmal failure!"); } else{ (void) pine_send_status(ps_global->post->status, ps_global->post->fcc, tmp_20k_buf, SIZEOF_20KBUF, &winner); q_status_message(SM_ORDER | (winner ? 0 : SM_DING), 3, 3, tmp_20k_buf); } if(!winner) q_status_message(SM_ORDER, 0, 3, "Re-send via \"Compose\" then \"Yes\" to \"Continue INTERRUPTED?\""); if(ps_global->post->fcc) fs_give((void **) &ps_global->post->fcc); fs_give((void **) &ps_global->post); } #endif /* * The character we get from read_char() is a UCS-4 char. Or it could be a special * value like KEY_UP or NO_OP_IDLE or something similar. From here on out * we're going to operate with UTF-8 internally. This is the point where we * convert the UCS-4 input (actually whatever sort of input the user is typing * was converted to UCS-4 first) to UTF-8. It's easy in this read_command * case because if user types a non-ascii character as a command it's going to be * an error. All commands are ascii. In order to present a reasonable error * message we pass back the UTF-8 string to the caller. */ if(ucs >= 0x80 && ucs < KEY_BASE){ /* * User typed a character that is non-ascii. Convert it to * UTF-8. */ memset(utf8buf, 0, sizeof(utf8buf)); newdestp = utf8_put(utf8buf, (unsigned long) ucs); if(newdestp - utf8buf > 1){ /* this should happen */ if(utf8str) *utf8str = (char *) utf8buf; dprint((9, "Read command: looks like user typed non-ascii command 0x%x %s: returning KEY_UTF8\n", ucs, pretty_command(ucs))); ucs = KEY_UTF8; } else{ dprint((9, "Read command: looks like user typed unknown, non-ascii command 0x%x %s: returning KEY_UNKNOWN\n", ucs, pretty_command(ucs))); ucs = KEY_UNKNOWN; /* best we can do, shouldn't happen */ } } else{ dprint((9, "Read command returning: 0x%x %s\n", ucs, pretty_command(ucs))); } return(ucs); }
/** * Returns a newly allocated string */ static char * json_parse_string(const char *s, const char **endp, const char **failp, const char **failmsg) { const char *start; char *r, *a, *b; int l, esc = 0; while(*s > 0 && *s < 33) s++; if(*s != '"') return NOT_THIS_TYPE; s++; start = s; while(1) { if(*s == 0) { *failmsg = "Unexpected end of JSON message"; *failp = s; return NULL; } if(*s == '\\') { esc = 1; } else if(*s == '"' && s[-1] != '\\') { *endp = s + 1; /* End */ l = s - start; r = malloc(l + 1); memcpy(r, start, l); r[l] = 0; if(esc) { /* Do deescaping inplace */ a = b = r; while(*a) { if(*a == '\\') { a++; if(*a == 'b') *b++ = '\b'; else if(*a == 'f') *b++ = '\f'; else if(*a == 'n') *b++ = '\n'; else if(*a == 'r') *b++ = '\r'; else if(*a == 't') *b++ = '\t'; else if(*a == 'u') { // Unicode character int i, v = 0; a++; for(i = 0; i < 4; i++) { v = v << 4; switch(a[i]) { case '0' ... '9': v |= a[i] - '0'; break; case 'a' ... 'f': v |= a[i] - 'a' + 10; break; case 'A' ... 'F': v |= a[i] - 'F' + 10; break; default: free(r); *failmsg = "Incorrect escape sequence"; *failp = (a - r) + start; return NULL; } } a+=3; b += utf8_put(b, v); } else { *b++ = *a; } a++; } else {
static int glw_text_bitmap_callback(glw_t *w, void *opaque, glw_signal_t signal, void *extra) { glw_text_bitmap_t *gtb = (void *)w; event_t *e; event_int_t *eu; switch(signal) { default: break; case GLW_SIGNAL_DESTROY: gtb_unbind(gtb); break; case GLW_SIGNAL_LAYOUT: glw_text_bitmap_layout(w, extra); break; case GLW_SIGNAL_INACTIVE: gtb_inactive(gtb); break; case GLW_SIGNAL_EVENT: if(w->glw_class == &glw_label) return 0; e = extra; if(event_is_action(e, ACTION_BS)) { del_char(gtb); gtb_notify(gtb); return 1; } else if(event_is_type(e, EVENT_UNICODE)) { eu = extra; if(insert_char(gtb, eu->val)) gtb_notify(gtb); return 1; } else if(event_is_action(e, ACTION_LEFT)) { if(gtb->gtb_edit_ptr > 0) { gtb->gtb_edit_ptr--; gtb->gtb_update_cursor = 1; return 1; } return 0; } else if(event_is_action(e, ACTION_RIGHT)) { if(gtb->gtb_edit_ptr < gtb->gtb_uc_len) { gtb->gtb_edit_ptr++; gtb->gtb_update_cursor = 1; return 1; } return 0; } else if(event_is_action(e, ACTION_ACTIVATE)) { if(w->glw_root->gr_open_osk != NULL) { char buf[512]; char *q = buf; int i; for(i = 0; i < gtb->gtb_uc_len; i++) q += utf8_put(q, gtb->gtb_uc_buffer[i]); *q = 0; w->glw_root->gr_open_osk(w->glw_root, NULL, buf, w, gtb->gtb_flags & GTB_PASSWORD); return 1; } } return 0; } return 0; }
/* * pico_readc - return char at current point. Up to calling routines * to keep cumulative count of chars. * The characters in PT are UCS-4 characters. The caller * of pico_readc is expecting UTF-8 chars. We convert * each UCS-4 character to a string of UTF-8 characters * and return them one at a time. */ int pico_readc(void *w, unsigned char *c, int flags) { int rv = 0; UCS ucs; static unsigned char obuf[6]; static unsigned char *obufpend = obuf; static unsigned char *obufpnext = obuf; if(!(flags & PICOREADC_NOUCS)){ if(obufpend > obuf){ *c = *obufpnext++; rv++; if(obufpnext >= obufpend){ obufpend = obuf; obufpnext = obuf; } return(rv); } } if(PT(w)->crinread){ *c = '\012'; /* return LF */ PT(w)->crinread = 0; rv++; } else if(PT(w)->doto < llength(PT(w)->dotp)){ /* normal char to return */ if(flags & PICOREADC_NOUCS){ *c = (unsigned char) lgetc(PT(w)->dotp, (PT(w)->doto)++).c; rv++; } else{ rv++; ucs = lgetc(PT(w)->dotp, (PT(w)->doto)++).c; obufpend = utf8_put(obuf, (unsigned long) ucs); obufpnext = obuf; if(obufpend > obuf){ *c = *obufpnext++; if(obufpnext >= obufpend){ obufpend = obuf; obufpnext = obuf; } } else *c = '?'; } } else if(PT(w)->dotp != PT(w)->linep){ /* return line break */ PT(w)->dotp = lforw(PT(w)->dotp); PT(w)->doto = 0; #if defined(DOS) || defined(OS2) *c = '\015'; PT(w)->crinread++; #else *c = '\012'; /* return local eol! */ #endif rv++; } /* else no chars to return */ return(rv); }