int main(int argc, char *argv[]) { int i; printf("1..2\n"); /* * C/POSIX locale. */ assert(btowc(EOF) == WEOF); assert(wctob(WEOF) == EOF); for (i = 0; i < UCHAR_MAX; i++) assert(btowc(i) == (wchar_t)i && i == (int)wctob(i)); /* * Japanese (EUC) locale. */ assert(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0); assert(MB_CUR_MAX > 1); assert(btowc('A') == L'A' && wctob(L'A') == 'A'); assert(btowc(0xa3) == WEOF && wctob(0xa3c1) == EOF); printf("ok 1 - btowc()\n"); printf("ok 2 - wctob()\n"); return (0); }
int main (int argc, char *argv[]) { int c; /* configure should already have checked that the locale is supported. */ if (setlocale (LC_ALL, "") == NULL) return 1; ASSERT (btowc (EOF) == WEOF); if (argc > 1) switch (argv[1][0]) { case '1': /* Locale encoding is ISO-8859-1 or ISO-8859-15. */ for (c = 0; c < 0x80; c++) ASSERT (btowc (c) == c); for (c = 0xA0; c < 0x100; c++) ASSERT (btowc (c) != WEOF); return 0; case '2': /* Locale encoding is UTF-8. */ for (c = 0; c < 0x80; c++) ASSERT (btowc (c) == c); for (c = 0x80; c < 0x100; c++) ASSERT (btowc (c) == WEOF); return 0; } return 1; }
/* * Write binary string to the file. * The output is ended either with '\n' (nl == true) * or '\0' (nl == false). */ size_t bwsfwrite(struct bwstring *bws, FILE *f, bool zero_ended) { if (MB_CUR_MAX == 1) { size_t len = bws->len; if (!zero_ended) { bws->data.cstr[len] = '\n'; if (fwrite(bws->data.cstr, len + 1, 1, f) < 1) err(2, NULL); bws->data.cstr[len] = '\0'; } else if (fwrite(bws->data.cstr, len + 1, 1, f) < 1) err(2, NULL); return (len + 1); } else { wchar_t eols; size_t printed = 0; eols = zero_ended ? btowc('\0') : btowc('\n'); while (printed < BWSLEN(bws)) { const wchar_t *s = bws->data.wstr + printed; if (*s == L'\0') { int nums; nums = fwprintf(f, L"%lc", *s); if (nums != 1) err(2, NULL); ++printed; } else { int nums; nums = fwprintf(f, L"%ls", s); if (nums < 1) err(2, NULL); printed += nums; } } fwprintf(f, L"%lc", eols); return (printed + 1); } }
/* Copies the source string (of char) into the destination string (of wchar_t) for a certain size * Terminates the destination string with \0 at ( size - 1 ) * Returns 1 if successful, -1 on error */ int8_t libewf_common_copy_char_to_wchar( wchar_t *destination, const char *source, size_t size ) { size_t iterator = 0; if( source == NULL ) { LIBEWF_WARNING_PRINT( "libewf_common_copy_char_to_wchar: invalid source.\n" ); return( -1 ); } if( destination == NULL ) { LIBEWF_WARNING_PRINT( "libewf_common_copy_char_to_wchar: invalid destination.\n" ); return( -1 ); } if( size > (size_t) SSIZE_MAX ) { LIBEWF_WARNING_PRINT( "libewf_common_copy_char_to_wchar: invalid size value exceeds maximum.\n" ); return( -1 ); } for( iterator = 0; iterator < size; iterator++ ) { destination[ iterator ] = (wchar_t) btowc( (int) source[ iterator ] ); } destination[ size - 1 ] = (wchar_t) '\0'; return( 1 ); }
wint_t _Locale_btowc(struct _Locale_ctype *__loc, int c) { wint_t _c; /* __c_locale __tmp = __uselocale( __loc ); */ _c = btowc( c ); /* __uselocale( __tmp ); */ return _c; }
/* * werase -- * Erases everything on the window. */ int werase(WINDOW *win) { int y; __LDATA *sp, *end, *start; attr_t attr; #ifdef DEBUG __CTRACE(__CTRACE_ERASE, "werase: (%p)\n", win); #endif if (win != curscr) attr = win->battr & __ATTRIBUTES; else attr = 0; for (y = 0; y < win->maxy; y++) { start = win->alines[y]->line; end = &start[win->maxx]; for (sp = start; sp < end; sp++) #ifndef HAVE_WCHAR if (sp->ch != win->bch || sp->attr != 0) { #else if (sp->ch != ( wchar_t )btowc(( int ) win->bch ) || (sp->attr & WA_ATTRIBUTES) != 0 || sp->nsp) { #endif /* HAVE_WCHAR */ if (sp->attr & __ALTCHARSET) sp->attr = attr | __ALTCHARSET; else sp->attr = attr; #ifdef HAVE_WCHAR sp->ch = ( wchar_t )btowc(( int ) win->bch); if (_cursesi_copy_nsp(win->bnsp, sp) == ERR) return ERR; SET_WCOL( *sp, 1 ); #else sp->ch = win->bch; #endif /* HAVE_WCHAR */ } } /* * Mark the whole window as changed in case we have overlapping * windows - this will result in the (intended) clearing of the * screen over the area covered by the window. */ __touchwin(win); wmove(win, 0, 0); return (OK); }
/* Expands a macro delimited by `regex' and `regex_end' to `buf', which must have at least `len' items. Sets buf[0] to zero if the there is no match in `tre_macros'. */ static void tre_expand_macro(const tre_char_t *regex, const tre_char_t *regex_end, tre_char_t *buf, size_t buf_len) { int i; size_t len = regex_end - regex; buf[0] = 0; for (i = 0; tre_macros[i] != NULL; i += 2) { int match = 0; if (strlen(tre_macros[i]) > len) continue; #ifdef TRE_WCHAR { tre_char_t tmp_wcs[64]; unsigned int j; for (j = 0; j < strlen(tre_macros[i]) && j < elementsof(tmp_wcs); j++) tmp_wcs[j] = btowc(tre_macros[i][j]); tmp_wcs[j] = 0; match = wcsncmp(tmp_wcs, regex, strlen(tre_macros[i])); } #else /* !TRE_WCHAR */ match = strncmp(tre_macros[i], regex, strlen(tre_macros[i])); #endif /* !TRE_WCHAR */ if (match == 0) { unsigned int j; DPRINT(("Expanding macro '%s' => '%s'\n", tre_macros[i], tre_macros[i + 1])); for (j = 0; tre_macros[i + 1][j] != 0 && j < buf_len; j++) { #ifdef TRE_WCHAR buf[j] = btowc(tre_macros[i + 1][j]); #else /* !TRE_WCHAR */ buf[j] = tre_macros[i + 1][j]; #endif /* !TRE_WCHAR */ } buf[j] = 0; break; } } }
WINDOW * __newwin(SCREEN *screen, int nlines, int ncols, int by, int bx, int ispad) { WINDOW *win; __LINE *lp; int i, j; int maxy, maxx; __LDATA *sp; if (by < 0 || bx < 0) return (NULL); maxy = nlines > 0 ? nlines : LINES - by + nlines; maxx = ncols > 0 ? ncols : COLS - bx + ncols; if ((win = __makenew(screen, maxy, maxx, by, bx, 0, ispad)) == NULL) return (NULL); win->bch = ' '; if (__using_color) win->battr = __default_color; else win->battr = 0; win->nextp = win; win->ch_off = 0; win->orig = NULL; win->reqy = nlines; win->reqx = ncols; #ifdef DEBUG __CTRACE(__CTRACE_WINDOW, "newwin: win->ch_off = %d\n", win->ch_off); #endif for (i = 0; i < maxy; i++) { lp = win->alines[i]; if (ispad) lp->flags = __ISDIRTY; else lp->flags = 0; for (sp = lp->line, j = 0; j < maxx; j++, sp++) { sp->attr = 0; #ifndef HAVE_WCHAR sp->ch = win->bch; #else sp->ch = ( wchar_t )btowc(( int ) win->bch ); sp->nsp = NULL; SET_WCOL( *sp, 1 ); #endif /* HAVE_WCHAR */ } lp->hash = __hash((char *)(void *)lp->line, (size_t) (ncols * __LDATASIZE)); } return (win); }
static wchar_t *itow (unsigned long int val) { static wchar_t buf[30]; wchar_t *wcp = &buf[29]; *wcp = L'\0'; while (val != 0) { *--wcp = btowc ('0' + val % 10); val /= 10; } if (wcp == &buf[29]) *--wcp = L'0'; return wcp; }
/* Test EOF handling. */ static int eof_test (void) { wint_t wc = btowc (EOF); if (wc != WEOF) { printf ("%s: btowc(EOF) returned L'\\x%x', not WEOF\n", current_locale, wc); } return 0; }
GLOBAL int test_btowc() { int i; char *locale; printf("1..2\n"); /* * C/POSIX locale. */ locale = setlocale(LC_CTYPE, "C"); assert(locale != NULL); assert(strcmp(locale, "C") == 0); assert(btowc(EOF) == WEOF); assert(wctob(WEOF) == EOF); for (i = 0; i < UCHAR_MAX; i++) assert(btowc(i) == (wchar_t)i && i == (int)wctob(i)); #if CRYSTAX_FULL_LOCALES /* * Japanese (EUC) locale. */ locale = setlocale(LC_CTYPE, "ja_JP.eucJP"); assert(locale != NULL); assert(strcmp(locale, "ja_JP.eucJP") == 0); assert(MB_CUR_MAX > 1); assert(btowc('A') == L'A' && wctob(L'A') == 'A'); assert(btowc(0xa3) == WEOF && wctob(0xa3c1) == EOF); #endif /* CRYSTAX_FULL_LOCALES */ printf("ok 1 - btowc()\n"); printf("ok 2 - wctob()\n"); return (0); }
/* Test which should succeed. */ static int ok_test (int c, wint_t expwc) { wint_t wc = btowc (c); if (wc != expwc) { printf ("%s: btowc('%c') failed, returned L'\\x%x' instead of L'\\x%x'\n", current_locale, c, wc, expwc); return 1; } return 0; }
/* Test which should fail. */ static int fail_test (int c) { wint_t wc = btowc (c); if (wc != WEOF) { printf ("%s: btowc('%c') succeded, returned L'\\x%x' instead of WEOF\n", current_locale, c, wc); return 1; } return 0; }
NCURSES_EXPORT(wint_t) _nc_to_widechar(int ch) { wint_t result; #if HAVE_BTOWC result = btowc(ch); #elif HAVE_MBTOWC wchar_t convert; char temp[2]; temp[0] = ch; temp[1] = '\0'; if (mbtowc(&convert, temp, 1) >= 0) result = convert; else result = WEOF; #endif return result; }
/* * wdelch -- * Do a delete-char on the line, leaving (cury, curx) unchanged. */ int wdelch(WINDOW *win) { __LDATA *end, *temp1, *temp2; int cw, sx; nschar_t *np, *tnp; end = &win->alines[win->cury]->line[win->maxx - 1]; sx = win->curx; temp1 = &win->alines[win->cury]->line[win->curx]; cw = WCOL( *temp1 ); if ( cw < 0 ) { temp1 += cw; sx += cw; cw = WCOL( *temp1 ); } np = temp1->nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } temp1->nsp = NULL; } if ( sx + cw < win->maxx ) { temp2 = temp1 + cw; while ( temp1 < end - ( cw - 1 )) { ( void )memcpy( temp1, temp2, sizeof( __LDATA )); temp1++, temp2++; } } while ( temp1 <= end ) { temp1->ch = ( wchar_t )btowc(( int ) win->bch ); temp1->attr = 0; if (_cursesi_copy_nsp(win->bnsp, temp1) == ERR) return ERR; SET_WCOL(*temp1, 1); temp1++; } __touchline(win, (int) win->cury, sx, (int) win->maxx - 1); return (OK); }
/* Converts an EWF character string to a LIBEWF character string * Returns 1 if successful, 0 if string was not set, or -1 on error */ int8_t libewf_string_copy_from_ewf_char( LIBEWF_CHAR *string, size_t size_string, EWF_CHAR *ewf_char_string, size_t size_ewf_char_string ) { size_t iterator = 0; if( string == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_copy_from_ewf_char: invalid string.\n" ); return( -1 ); } if( ewf_char_string == NULL ) { LIBEWF_WARNING_PRINT( "libewf_string_copy_from_ewf_char: invalid EWF character string.\n" ); return( -1 ); } if( ( size_string > (size_t) SSIZE_MAX ) || ( size_ewf_char_string > (size_t) SSIZE_MAX ) ) { LIBEWF_WARNING_PRINT( "libewf_string_copy_from_ewf_char: invalid size value exceeds maximum.\n" ); return( -1 ); } if( size_string < size_ewf_char_string ) { LIBEWF_WARNING_PRINT( "libewf_string_copy_from_ewf_char: string too small.\n" ); return( -1 ); } for( iterator = 0; iterator < size_ewf_char_string; iterator++ ) { #ifdef HAVE_WIDE_CHARACTER_TYPE string[ iterator ] = btowc( (int) ewf_char_string[ iterator ] ); #else string[ iterator ] = (char) ewf_char_string[ iterator ]; #endif } string[ size_ewf_char_string - 1 ] = (LIBEWF_CHAR) '\0'; return( 1 ); }
ssize_t WideTtyCvt( CHAR16 *dest, const char *buf, size_t n) { UINTN i; wint_t wc; for(i = 0; i < n; ++i) { wc = btowc(*buf++); if( wc == 0) { break; }; if(wc < 0) { wc = BLOCKELEMENT_LIGHT_SHADE; } if(wc == L'\n') { *dest++ = L'\r'; } *dest++ = (CHAR16)wc; } *dest = 0; return (ssize_t)i; }
int wborder_set(WINDOW *win, const cchar_t *ls, const cchar_t *rs, const cchar_t *ts, const cchar_t *bs, const cchar_t *tl, const cchar_t *tr, const cchar_t *bl, const cchar_t *br) { #ifndef HAVE_WCHAR return ERR; #else int endy, endx, i, j, k, cw, pcw, tlcw, blcw, trcw, brcw; cchar_t left, right, bottom, top, topleft, topright, botleft, botright; nschar_t *np, *tnp; if ( ls && wcwidth( ls->vals[ 0 ])) memcpy( &left, ls, sizeof( cchar_t )); else memcpy( &left, WACS_VLINE, sizeof( cchar_t )); if ( rs && wcwidth( rs->vals[ 0 ])) memcpy( &right, rs, sizeof( cchar_t )); else memcpy( &right, WACS_VLINE, sizeof( cchar_t )); if ( ts && wcwidth( ts->vals[ 0 ])) memcpy( &top, ts, sizeof( cchar_t )); else memcpy( &top, WACS_HLINE, sizeof( cchar_t )); if ( bs && wcwidth( bs->vals[ 0 ])) memcpy( &bottom, bs, sizeof( cchar_t )); else memcpy( &bottom, WACS_HLINE, sizeof( cchar_t )); if ( tl && wcwidth( tl->vals[ 0 ])) memcpy( &topleft, tl, sizeof( cchar_t )); else memcpy( &topleft, WACS_ULCORNER, sizeof( cchar_t )); if ( tr && wcwidth( tr->vals[ 0 ])) memcpy( &topright, tr, sizeof( cchar_t )); else memcpy( &topright, WACS_URCORNER, sizeof( cchar_t )); if ( bl && wcwidth( bl->vals[ 0 ])) memcpy( &botleft, bl, sizeof( cchar_t )); else memcpy( &botleft, WACS_LLCORNER, sizeof( cchar_t )); if ( br && wcwidth( br->vals[ 0 ])) memcpy( &botright, br, sizeof( cchar_t )); else memcpy( &botright, WACS_LRCORNER, sizeof( cchar_t )); #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "wborder_set: left = %c, 0x%x\n", left.vals[0], left.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: right = %c, 0x%x\n", right.vals[0], right.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: top = %c, 0x%x\n", top.vals[0], top.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: bottom = %c, 0x%x\n", bottom.vals[0], bottom.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: topleft = %c, 0x%x\n", topleft.vals[0], topleft.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: topright = %c, 0x%x\n", topright.vals[0], topright.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: botleft = %c, 0x%x\n", botleft.vals[0], botleft.attributes ); __CTRACE(__CTRACE_INPUT, "wborder_set: botright = %c, 0x%x\n", botright.vals[0], botright.attributes ); #endif /* Merge window attributes */ left.attributes |= (left.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; left.attributes |= (left.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; right.attributes |= (right.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; right.attributes |= (right.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; top.attributes |= (top.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; top.attributes |= (top.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; bottom.attributes |= (bottom.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; bottom.attributes |= (bottom.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; topleft.attributes |= (topleft.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; topleft.attributes |= (topleft.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; topright.attributes |= (topright.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; topright.attributes |= (topright.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; botleft.attributes |= (botleft.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; botleft.attributes |= (botleft.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; botright.attributes |= (botright.attributes & __COLOR) ? (win->wattr & ~__COLOR) : win->wattr; botright.attributes |= (botright.attributes & __COLOR) ? (win->battr & ~__COLOR) : win->battr; endx = win->maxx - 1; endy = win->maxy - 1; /* Sides */ for (i = 1; i < endy; i++) { /* left border */ cw = wcwidth( left.vals[ 0 ]); if (cw < 0) cw = 1; for ( j = 0; j < cw; j++ ) { win->alines[i]->line[j].ch = left.vals[ 0 ]; win->alines[i]->line[j].attr = left.attributes; np = win->alines[i]->line[j].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[i]->line[j].nsp = NULL; } if ( j ) SET_WCOL( win->alines[i]->line[j], -j ); else { SET_WCOL( win->alines[i]->line[j], cw ); if ( left.elements > 1 ) { for (k = 1; k < left.elements; k++) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = left.vals[ k ]; np->next = win->alines[i]->line[j].nsp; win->alines[i]->line[j].nsp = np; } } } } for ( j = cw; WCOL( win->alines[i]->line[j]) < 0; j++ ) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "wborder_set: clean out partial char[%d]", j); #endif /* DEBUG */ win->alines[i]->line[j].ch = ( wchar_t )btowc(win->bch); if (_cursesi_copy_nsp(win->bnsp, &win->alines[i]->line[j]) == ERR) return ERR; SET_WCOL( win->alines[i]->line[j], 1 ); } /* right border */ cw = wcwidth( right.vals[ 0 ]); if (cw < 0) cw = 1; pcw = WCOL( win->alines[i]->line[endx - cw]); for ( j = endx - cw + 1; j <= endx; j++ ) { win->alines[i]->line[j].ch = right.vals[ 0 ]; win->alines[i]->line[j].attr = right.attributes; np = win->alines[i]->line[j].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[i]->line[j].nsp = NULL; } if ( j == endx - cw + 1 ) { SET_WCOL( win->alines[i]->line[j], cw ); if ( right.elements > 1 ) { for (k = 1; k < right.elements; k++) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = right.vals[ k ]; np->next = win->alines[i]->line[j].nsp; win->alines[i]->line[j].nsp = np; } } } else SET_WCOL( win->alines[i]->line[j], endx - cw + 1 - j ); } if ( pcw != 1 ) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "wborder_set: clean out partial chars[%d:%d]", endx - cw + pcw, endx - cw ); #endif /* DEBUG */ k = pcw < 0 ? endx -cw + pcw : endx - cw; for ( j = endx - cw; j >= k; j-- ) { win->alines[i]->line[j].ch = (wchar_t)btowc(win->bch); if (_cursesi_copy_nsp(win->bnsp, &win->alines[i]->line[j]) == ERR) return ERR; win->alines[i]->line[j].attr = win->battr; SET_WCOL( win->alines[i]->line[j], 1 ); } } } tlcw = wcwidth( topleft.vals[ 0 ]); if (tlcw < 0) tlcw = 1; blcw = wcwidth( botleft.vals[ 0 ]); if (blcw < 0) blcw = 1; trcw = wcwidth( topright.vals[ 0 ]); if (trcw < 0) trcw = 1; brcw = wcwidth( botright.vals[ 0 ]); if (brcw < 0) brcw = 1; /* upper border */ cw = wcwidth( top.vals[ 0 ]); if (cw < 0) cw = 1; for (i = tlcw; i <= min( endx - cw, endx - trcw ); i += cw ) { for ( j = 0; j < cw; j++ ) { win->alines[ 0 ]->line[i + j].ch = top.vals[ 0 ]; win->alines[ 0 ]->line[i + j].attr = top.attributes; np = win->alines[ 0 ]->line[i + j].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ 0 ]->line[i + j].nsp = NULL; } if ( j ) SET_WCOL( win->alines[ 0 ]->line[ i + j ], -j ); else { SET_WCOL( win->alines[ 0 ]->line[ i + j ], cw ); if ( top.elements > 1 ) { for ( k = 1; k < top.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = top.vals[ k ]; np->next = win->alines[0]->line[i + j].nsp; win->alines[0]->line[i + j].nsp = np; } } } } } while ( i <= endx - trcw ) { win->alines[0]->line[i].ch = ( wchar_t )btowc(( int ) win->bch ); if (_cursesi_copy_nsp(win->bnsp, &win->alines[0]->line[i]) == ERR) return ERR; win->alines[ 0 ]->line[ i ].attr = win->battr; SET_WCOL( win->alines[ 0 ]->line[ i ], 1 ); i++; } /* lower border */ for (i = blcw; i <= min( endx - cw, endx - brcw ); i += cw ) { for ( j = 0; j < cw; j++ ) { win->alines[ endy ]->line[i + j].ch = bottom.vals[ 0 ]; win->alines[endy]->line[i + j].attr = bottom.attributes; np = win->alines[ endy ]->line[i + j].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ endy ]->line[i + j].nsp = NULL; } if ( j ) SET_WCOL( win->alines[endy]->line[i + j], -j); else { SET_WCOL( win->alines[endy]->line[i + j], cw ); if ( bottom.elements > 1 ) { for ( k = 1; k < bottom.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = bottom.vals[ k ]; np->next = win->alines[endy]->line[i + j].nsp; win->alines[endy]->line[i + j].nsp = np; } } } } } while ( i <= endx - brcw ) { win->alines[endy]->line[i].ch = (wchar_t)btowc((int) win->bch ); if (_cursesi_copy_nsp(win->bnsp, &win->alines[endy]->line[i]) == ERR) return ERR; win->alines[ endy ]->line[ i ].attr = win->battr; SET_WCOL( win->alines[ endy ]->line[ i ], 1 ); i++; } /* Corners */ if (!(win->maxx == LINES && win->maxy == COLS && (win->flags & __SCROLLOK) && (win->flags & __SCROLLWIN))) { for ( i = 0; i < tlcw; i++ ) { win->alines[ 0 ]->line[i].ch = topleft.vals[ 0 ]; win->alines[ 0 ]->line[i].attr = topleft.attributes; np = win->alines[ 0 ]->line[i].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ 0 ]->line[i].nsp = NULL; } if ( i ) SET_WCOL( win->alines[ 0 ]->line[ i ], -i ); else { SET_WCOL( win->alines[ 0 ]->line[ i ], tlcw ); if ( topleft.elements > 1 ) { for ( k = 1; k < topleft.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = topleft.vals[ k ]; np->next = win->alines[ 0 ]->line[i].nsp; win->alines[ 0 ]->line[i].nsp = np; } } } } for ( i = endx - trcw + 1; i <= endx; i++ ) { win->alines[ 0 ]->line[i].ch = topright.vals[ 0 ]; win->alines[ 0 ]->line[i].attr = topright.attributes; np = win->alines[ 0 ]->line[i].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ 0 ]->line[i].nsp = NULL; } if ( i == endx - trcw + 1 ) { SET_WCOL( win->alines[ 0 ]->line[ i ], trcw ); if ( topright.elements > 1 ) { for ( k = 1; k < topright.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = topright.vals[ k ]; np->next = win->alines[0]->line[i].nsp; win->alines[ 0 ]->line[i].nsp = np; } } } else SET_WCOL( win->alines[ 0 ]->line[ i ], endx - trcw + 1 - i ); } for ( i = 0; i < blcw; i++ ) { win->alines[ endy ]->line[i].ch = botleft.vals[ 0 ]; win->alines[ endy ]->line[i].attr = botleft.attributes; np = win->alines[ endy ]->line[i].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ endy ]->line[i].nsp = NULL; } if ( i ) SET_WCOL( win->alines[endy]->line[i], -i ); else { SET_WCOL( win->alines[endy]->line[i], blcw ); if ( botleft.elements > 1 ) { for ( k = 1; k < botleft.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = botleft.vals[ k ]; np->next = win->alines[endy]->line[i].nsp; win->alines[endy]->line[i].nsp = np; } } } } for ( i = endx - brcw + 1; i <= endx; i++ ) { win->alines[ endy ]->line[i].ch = botright.vals[ 0 ]; win->alines[ endy ]->line[i].attr = botright.attributes; np = win->alines[ endy ]->line[i].nsp; if (np) { while ( np ) { tnp = np->next; free( np ); np = tnp; } win->alines[ endy ]->line[i].nsp = NULL; } if ( i == endx - brcw + 1 ) { SET_WCOL( win->alines[ endy ]->line[ i ], brcw ); if ( botright.elements > 1 ) { for ( k = 1; k < botright.elements; k++ ) { np = malloc(sizeof(nschar_t)); if (!np) return ERR; np->ch = botright.vals[ k ]; np->next = win->alines[endy]->line[i].nsp; win->alines[endy]->line[i].nsp = np; } } } else SET_WCOL( win->alines[ endy ]->line[ i ], endx - brcw + 1 - i ); } } __touchwin(win); return (OK); #endif /* HAVE_WCHAR */ }
void main( void ) { printf( "EOF is %sa valid single-byte character\n", btowc( EOF ) == WEOF ? "not " : "" ); }
static int test_one_locale (const char *name, int codepage) { char buf[64]; size_t ret; # if 1 /* Portable code to set the locale. */ { char name_with_codepage[1024]; sprintf (name_with_codepage, "%s.%d", name, codepage); /* Set the locale. */ if (setlocale (LC_ALL, name_with_codepage) == NULL) return 77; } # else /* Hacky way to set a locale.codepage combination that setlocale() refuses to set. */ { /* Codepage of the current locale, set with setlocale(). Not necessarily the same as GetACP(). */ extern __declspec(dllimport) unsigned int __lc_codepage; /* Set the locale. */ if (setlocale (LC_ALL, name) == NULL) return 77; /* Clobber the codepage and MB_CUR_MAX, both set by setlocale(). */ __lc_codepage = codepage; switch (codepage) { case 1252: case 1256: MB_CUR_MAX = 1; break; case 932: case 950: case 936: MB_CUR_MAX = 2; break; case 54936: case 65001: MB_CUR_MAX = 4; break; } /* Test whether the codepage is really available. */ { mbstate_t state; wchar_t wc; memset (&state, '\0', sizeof (mbstate_t)); if (mbrtowc (&wc, " ", 1, &state) == (size_t)(-1)) return 77; } } # endif /* Test NUL character. */ { buf[0] = 'x'; ret = wcrtomb (buf, 0, NULL); ASSERT (ret == 1); ASSERT (buf[0] == '\0'); } /* Test single bytes. */ { int c; for (c = 0; c < 0x100; c++) switch (c) { case '\t': case '\v': case '\f': case ' ': case '!': case '"': case '#': case '%': case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case '-': case '.': case '/': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ':': case ';': case '<': case '=': case '>': case '?': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '[': case '\\': case ']': case '^': case '_': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '{': case '|': case '}': case '~': /* c is in the ISO C "basic character set". */ ret = wcrtomb (buf, btowc (c), NULL); ASSERT (ret == 1); ASSERT (buf[0] == (char) c); break; } } /* Test special calling convention, passing a NULL pointer. */ { ret = wcrtomb (NULL, '\0', NULL); ASSERT (ret == 1); ret = wcrtomb (NULL, btowc ('x'), NULL); ASSERT (ret == 1); } switch (codepage) { case 1252: /* Locale encoding is CP1252, an extension of ISO-8859-1. */ { /* Convert "B\374\337er": "Büßer" */ memset (buf, 'x', 8); ret = wcrtomb (buf, 0x00FC, NULL); ASSERT (ret == 1); ASSERT (memcmp (buf, "\374", 1) == 0); ASSERT (buf[1] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x00DF, NULL); ASSERT (ret == 1); ASSERT (memcmp (buf, "\337", 1) == 0); ASSERT (buf[1] == 'x'); } return 0; case 1256: /* Locale encoding is CP1256, not the same as ISO-8859-6. */ { /* Convert "x\302\341\346y": "xآلوy" */ memset (buf, 'x', 8); ret = wcrtomb (buf, 0x0622, NULL); ASSERT (ret == 1); ASSERT (memcmp (buf, "\302", 1) == 0); ASSERT (buf[1] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x0644, NULL); ASSERT (ret == 1); ASSERT (memcmp (buf, "\341", 1) == 0); ASSERT (buf[1] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x0648, NULL); ASSERT (ret == 1); ASSERT (memcmp (buf, "\346", 1) == 0); ASSERT (buf[1] == 'x'); } return 0; case 932: /* Locale encoding is CP932, similar to Shift_JIS. */ { /* Convert "<\223\372\226\173\214\352>": "<日本語>" */ memset (buf, 'x', 8); ret = wcrtomb (buf, 0x65E5, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\223\372", 2) == 0); ASSERT (buf[2] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x672C, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\226\173", 2) == 0); ASSERT (buf[2] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x8A9E, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\214\352", 2) == 0); ASSERT (buf[2] == 'x'); } return 0; case 950: /* Locale encoding is CP950, similar to Big5. */ { /* Convert "<\244\351\245\273\273\171>": "<日本語>" */ memset (buf, 'x', 8); ret = wcrtomb (buf, 0x65E5, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\244\351", 2) == 0); ASSERT (buf[2] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x672C, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\245\273", 2) == 0); ASSERT (buf[2] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x8A9E, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\273\171", 2) == 0); ASSERT (buf[2] == 'x'); } return 0; case 936: /* Locale encoding is CP936 = GBK, an extension of GB2312. */ { /* Convert "<\310\325\261\276\325\132>": "<日本語>" */ memset (buf, 'x', 8); ret = wcrtomb (buf, 0x65E5, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\310\325", 2) == 0); ASSERT (buf[2] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x672C, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\261\276", 2) == 0); ASSERT (buf[2] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x8A9E, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\325\132", 2) == 0); ASSERT (buf[2] == 'x'); } return 0; case 54936: /* Locale encoding is CP54936 = GB18030. */ { /* Convert "B\250\271\201\060\211\070er": "Büßer" */ memset (buf, 'x', 8); ret = wcrtomb (buf, 0x00FC, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\250\271", 2) == 0); ASSERT (buf[2] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x00DF, NULL); ASSERT (ret == 4); ASSERT (memcmp (buf, "\201\060\211\070", 4) == 0); ASSERT (buf[4] == 'x'); } return 0; case 65001: /* Locale encoding is CP65001 = UTF-8. */ { /* Convert "B\303\274\303\237er": "Büßer" */ memset (buf, 'x', 8); ret = wcrtomb (buf, 0x00FC, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\303\274", 2) == 0); ASSERT (buf[2] == 'x'); memset (buf, 'x', 8); ret = wcrtomb (buf, 0x00DF, NULL); ASSERT (ret == 2); ASSERT (memcmp (buf, "\303\237", 2) == 0); ASSERT (buf[2] == 'x'); } return 0; default: return 1; } }
/* * __init_wacs -- * Fill in the ACS characters. The 'acs_chars' terminfo entry is a list of * character pairs - ACS definition then terminal representation. */ void __init_wacs(SCREEN *screen) { int count; const char *aofac; /* Address of 'ac' */ unsigned char acs, term; char *lstr; /* Default value '+' for all ACS characters */ for (count=0; count < NUM_ACS; count++) { _wacs_char[ count ].vals[ 0 ] = ( wchar_t )btowc( '+' ); _wacs_char[ count ].attributes = 0; _wacs_char[ count ].elements = 1; } /* Add the SUSv2 defaults (those that are not '+') */ if (!strcmp(setlocale(LC_CTYPE, NULL), "C")) setlocale(LC_CTYPE, ""); lstr = nl_langinfo(CODESET); _DIAGASSERT(lstr); if (strcasecmp(lstr, "UTF-8")) { #ifdef DEBUG __CTRACE(__CTRACE_INIT, "__init_wacs: setting defaults\n" ); #endif /* DEBUG */ WACS_RARROW->vals[0] = ( wchar_t )btowc( '>' ); WACS_LARROW->vals[0] = ( wchar_t )btowc( '<' ); WACS_UARROW->vals[0] = ( wchar_t )btowc( '^' ); WACS_DARROW->vals[0] = ( wchar_t )btowc( 'v' ); WACS_BLOCK->vals[0] = ( wchar_t )btowc( '#' ); WACS_CKBOARD->vals[0] = ( wchar_t )btowc( ':' ); WACS_DEGREE->vals[0] = ( wchar_t )btowc( 39 ); /* ' */ WACS_PLMINUS->vals[0] = ( wchar_t )btowc( '#' ); WACS_BOARD->vals[0] = ( wchar_t )btowc( '#' ); WACS_LANTERN->vals[0] = ( wchar_t )btowc( '#' ); WACS_HLINE->vals[0] = ( wchar_t )btowc( '-' ); WACS_S1->vals[0] = ( wchar_t )btowc( '-' ); WACS_S9->vals[0] = ( wchar_t )btowc( '_' ); WACS_VLINE->vals[0] = ( wchar_t )btowc( '|' ); WACS_BULLET->vals[0] = ( wchar_t )btowc( 'o' ); WACS_S3->vals[0] = ( wchar_t )btowc( 'p' ); WACS_S7->vals[0] = ( wchar_t )btowc( 'r' ); WACS_LEQUAL->vals[0] = ( wchar_t )btowc( 'y' ); WACS_GEQUAL->vals[0] = ( wchar_t )btowc( 'z' ); WACS_PI->vals[0] = ( wchar_t )btowc( '{' ); WACS_NEQUAL->vals[0] = ( wchar_t )btowc( '|' ); WACS_STERLING->vals[0]= ( wchar_t )btowc( '}' ); } else { /* Unicode defaults */ #ifdef DEBUG __CTRACE(__CTRACE_INIT, "__init_wacs: setting Unicode defaults\n" ); #endif /* DEBUG */ WACS_RARROW->vals[0] = 0x2192; ACS_RARROW = '+' | __ACS_IS_WACS; WACS_LARROW->vals[0] = 0x2190; ACS_LARROW = ',' | __ACS_IS_WACS; WACS_UARROW->vals[0] = 0x2191; ACS_UARROW = '-' | __ACS_IS_WACS; WACS_DARROW->vals[0] = 0x2193; ACS_DARROW = '.' | __ACS_IS_WACS; WACS_BLOCK->vals[0] = 0x25ae; ACS_BLOCK = '0' | __ACS_IS_WACS; WACS_DIAMOND->vals[0] = 0x25c6; ACS_DIAMOND = '`' | __ACS_IS_WACS; WACS_CKBOARD->vals[0] = 0x2592; ACS_CKBOARD = 'a' | __ACS_IS_WACS; WACS_DEGREE->vals[0] = 0x00b0; ACS_DEGREE = 'f' | __ACS_IS_WACS; WACS_PLMINUS->vals[0] = 0x00b1; ACS_PLMINUS = 'g' | __ACS_IS_WACS; WACS_BOARD->vals[0] = 0x2592; ACS_BOARD = 'h' | __ACS_IS_WACS; WACS_LANTERN->vals[0] = 0x2603; ACS_LANTERN = 'i' | __ACS_IS_WACS; WACS_LRCORNER->vals[0]= 0x2518; ACS_LRCORNER = 'j' | __ACS_IS_WACS; WACS_URCORNER->vals[0]= 0x2510; ACS_URCORNER = 'k' | __ACS_IS_WACS; WACS_ULCORNER->vals[0]= 0x250c; ACS_ULCORNER = 'l' | __ACS_IS_WACS; WACS_LLCORNER->vals[0]= 0x2514; ACS_LLCORNER = 'm' | __ACS_IS_WACS; WACS_PLUS->vals[0] = 0x253c; ACS_PLUS = 'n' | __ACS_IS_WACS; WACS_HLINE->vals[0] = 0x2500; ACS_HLINE = 'q' | __ACS_IS_WACS; WACS_S1->vals[0] = 0x23ba; ACS_S1 = 'o' | __ACS_IS_WACS; WACS_S9->vals[0] = 0x23bd; ACS_S9 = 's' | __ACS_IS_WACS; WACS_LTEE->vals[0] = 0x251c; ACS_LTEE = 't' | __ACS_IS_WACS; WACS_RTEE->vals[0] = 0x2524; ACS_RTEE = 'u' | __ACS_IS_WACS; WACS_BTEE->vals[0] = 0x2534; ACS_BTEE = 'v' | __ACS_IS_WACS; WACS_TTEE->vals[0] = 0x252c; ACS_TTEE = 'w' | __ACS_IS_WACS; WACS_VLINE->vals[0] = 0x2502; ACS_VLINE = 'x' | __ACS_IS_WACS; WACS_BULLET->vals[0] = 0x00b7; ACS_BULLET = '~' | __ACS_IS_WACS; WACS_S3->vals[0] = 0x23bb; ACS_S3 = 'p' | __ACS_IS_WACS; WACS_S7->vals[0] = 0x23bc; ACS_S7 = 'r' | __ACS_IS_WACS; WACS_LEQUAL->vals[0] = 0x2264; ACS_LEQUAL = 'y' | __ACS_IS_WACS; WACS_GEQUAL->vals[0] = 0x2265; ACS_GEQUAL = 'z' | __ACS_IS_WACS; WACS_PI->vals[0] = 0x03C0; ACS_PI = '{' | __ACS_IS_WACS; WACS_NEQUAL->vals[0] = 0x2260; ACS_NEQUAL = '|' | __ACS_IS_WACS; WACS_STERLING->vals[0]= 0x00A3; ACS_STERLING = '}' | __ACS_IS_WACS; } if (t_acs_chars(screen->term) == NULL) { #ifdef DEBUG __CTRACE(__CTRACE_INIT, "__init_wacs: no alternative characters\n" ); #endif /* DEBUG */ goto out; } aofac = t_acs_chars(screen->term); while (*aofac != '\0') { if ((acs = *aofac) == '\0') return; if ((term = *++aofac) == '\0') return; /* Only add characters 1 to 127 */ if (acs < NUM_ACS) { _wacs_char[acs].vals[ 0 ] = term; _wacs_char[acs].attributes |= WA_ALTCHARSET; } aofac++; #ifdef DEBUG __CTRACE(__CTRACE_INIT, "__init_wacs: %c = %c\n", acs, term); #endif } if (t_ena_acs(screen->term) != NULL) ti_puts(screen->term, t_ena_acs(screen->term), 0, __cputchar_args, screen->outfd); out: for (count=0; count < NUM_ACS; count++) { memcpy(&screen->wacs_char[count], &_wacs_char[count], sizeof(cchar_t)); screen->acs_char[count]= _acs_char[count]; } }
int main (int argc, char *argv[]) { char buf[64]; size_t ret; /* configure should already have checked that the locale is supported. */ if (setlocale (LC_ALL, "") == NULL) return 1; /* Test NUL character. */ { buf[0] = 'x'; ret = wcrtomb (buf, 0, NULL); ASSERT (ret == 1); ASSERT (buf[0] == '\0'); } /* Test single bytes. */ { int c; for (c = 0; c < 0x100; c++) switch (c) { case '\t': case '\v': case '\f': case ' ': case '!': case '"': case '#': case '%': case '&': case '\'': case '(': case ')': case '*': case '+': case ',': case '-': case '.': case '/': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ':': case ';': case '<': case '=': case '>': case '?': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '[': case '\\': case ']': case '^': case '_': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case '{': case '|': case '}': case '~': /* c is in the ISO C "basic character set". */ ret = wcrtomb (buf, btowc (c), NULL); ASSERT (ret == 1); ASSERT (buf[0] == (char) c); break; } } /* Test special calling convention, passing a NULL pointer. */ { ret = wcrtomb (NULL, '\0', NULL); ASSERT (ret == 1); ret = wcrtomb (NULL, btowc ('x'), NULL); ASSERT (ret == 1); } if (argc > 1) switch (argv[1][0]) { case '1': /* Locale encoding is ISO-8859-1 or ISO-8859-15. */ { const char input[] = "B\374\337er"; /* "Büßer" */ check_character (input + 1, 1); check_character (input + 2, 1); } return 0; case '2': /* Locale encoding is UTF-8. */ { const char input[] = "B\303\274\303\237er"; /* "Büßer" */ check_character (input + 1, 2); check_character (input + 3, 2); } return 0; case '3': /* Locale encoding is EUC-JP. */ { const char input[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */ check_character (input + 1, 2); check_character (input + 3, 2); check_character (input + 5, 2); } return 0; case '4': /* Locale encoding is GB18030. */ { const char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */ check_character (input + 1, 2); check_character (input + 3, 4); } return 0; } return 1; }
int main() { mbstate_t mb = {0}; size_t s = 0; tm tm = {0}; wint_t w = 0; ::FILE* fp = 0; __darwin_va_list va; char* ns = 0; wchar_t* ws = 0; static_assert((std::is_same<decltype(fwprintf(fp, L"")), int>::value), ""); static_assert((std::is_same<decltype(fwscanf(fp, L"")), int>::value), ""); static_assert((std::is_same<decltype(swprintf(ws, s, L"")), int>::value), ""); static_assert((std::is_same<decltype(swscanf(L"", L"")), int>::value), ""); static_assert((std::is_same<decltype(vfwprintf(fp, L"", va)), int>::value), ""); static_assert((std::is_same<decltype(vfwscanf(fp, L"", va)), int>::value), ""); static_assert((std::is_same<decltype(vswprintf(ws, s, L"", va)), int>::value), ""); static_assert((std::is_same<decltype(vswscanf(L"", L"", va)), int>::value), ""); static_assert((std::is_same<decltype(vwprintf(L"", va)), int>::value), ""); static_assert((std::is_same<decltype(vwscanf(L"", va)), int>::value), ""); static_assert((std::is_same<decltype(wprintf(L"")), int>::value), ""); static_assert((std::is_same<decltype(wscanf(L"")), int>::value), ""); static_assert((std::is_same<decltype(fgetwc(fp)), wint_t>::value), ""); static_assert((std::is_same<decltype(fgetws(ws, 0, fp)), wchar_t*>::value), ""); static_assert((std::is_same<decltype(fputwc(L' ', fp)), wint_t>::value), ""); static_assert((std::is_same<decltype(fputws(L"", fp)), int>::value), ""); static_assert((std::is_same<decltype(fwide(fp, 0)), int>::value), ""); static_assert((std::is_same<decltype(getwc(fp)), wint_t>::value), ""); static_assert((std::is_same<decltype(getwchar()), wint_t>::value), ""); static_assert((std::is_same<decltype(putwc(L' ', fp)), wint_t>::value), ""); static_assert((std::is_same<decltype(putwchar(L' ')), wint_t>::value), ""); static_assert((std::is_same<decltype(ungetwc(L' ', fp)), wint_t>::value), ""); static_assert((std::is_same<decltype(wcstod(L"", (wchar_t**)0)), double>::value), ""); static_assert((std::is_same<decltype(wcstof(L"", (wchar_t**)0)), float>::value), ""); static_assert((std::is_same<decltype(wcstold(L"", (wchar_t**)0)), long double>::value), ""); static_assert((std::is_same<decltype(wcstol(L"", (wchar_t**)0, 0)), long>::value), ""); static_assert((std::is_same<decltype(wcstoll(L"", (wchar_t**)0, 0)), long long>::value), ""); static_assert((std::is_same<decltype(wcstoul(L"", (wchar_t**)0, 0)), unsigned long>::value), ""); static_assert((std::is_same<decltype(wcstoull(L"", (wchar_t**)0, 0)), unsigned long long>::value), ""); static_assert((std::is_same<decltype(wcscpy(ws, L"")), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcsncpy(ws, L"", s)), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcscat(ws, L"")), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcsncat(ws, L"", s)), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcscmp(L"", L"")), int>::value), ""); static_assert((std::is_same<decltype(wcscoll(L"", L"")), int>::value), ""); static_assert((std::is_same<decltype(wcsncmp(L"", L"", s)), int>::value), ""); static_assert((std::is_same<decltype(wcsxfrm(ws, L"", s)), size_t>::value), ""); static_assert((std::is_same<decltype(wcschr((wchar_t*)0, L' ')), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcscspn(L"", L"")), size_t>::value), ""); static_assert((std::is_same<decltype(wcslen(L"")), size_t>::value), ""); static_assert((std::is_same<decltype(wcspbrk((wchar_t*)0, L"")), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcsrchr((wchar_t*)0, L' ')), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcsspn(L"", L"")), size_t>::value), ""); static_assert((std::is_same<decltype(wcsstr((wchar_t*)0, L"")), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcstok(ws, L"", (wchar_t**)0)), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wmemchr((wchar_t*)0, L' ', s)), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wmemcmp(L"", L"", s)), int>::value), ""); static_assert((std::is_same<decltype(wmemcpy(ws, L"", s)), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wmemmove(ws, L"", s)), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wmemset(ws, L' ', s)), wchar_t*>::value), ""); static_assert((std::is_same<decltype(wcsftime(ws, s, L"", &tm)), size_t>::value), ""); static_assert((std::is_same<decltype(btowc(0)), wint_t>::value), ""); static_assert((std::is_same<decltype(wctob(w)), int>::value), ""); static_assert((std::is_same<decltype(mbsinit(&mb)), int>::value), ""); static_assert((std::is_same<decltype(mbrlen("", s, &mb)), size_t>::value), ""); static_assert((std::is_same<decltype(mbrtowc(ws, "", s, &mb)), size_t>::value), ""); static_assert((std::is_same<decltype(wcrtomb(ns, L' ', &mb)), size_t>::value), ""); static_assert((std::is_same<decltype(mbsrtowcs(ws, (const char**)0, s, &mb)), size_t>::value), ""); static_assert((std::is_same<decltype(wcsrtombs(ns, (const wchar_t**)0, s, &mb)), size_t>::value), ""); }
int _WStoflt(const wchar_t *s0, const wchar_t *s, wchar_t **endptr, long lo[], int maxsig) { /* convert wide string to array of long plus exponent */ char buf[MAXSIG + 1]; /* worst case, with room for rounding digit */ int nsig = 0; /* number of significant digits seen */ int seen = 0; /* any valid field characters seen */ int word = 0; /* current long word to fill */ maxsig *= NDIG; /* convert word count to digit count */ if (MAXSIG < maxsig) { maxsig = MAXSIG; /* protect against bad call */ } lo[0] = 0; /* power of ten exponent */ lo[1] = 0; /* first NDIG-digit word of fraction */ while (*s == L'0') { /* strip leading zeros */ ++s; seen = 1; } while (iswdigit(*s)) { if (nsig <= maxsig) { buf[nsig++] = (char)(*s - L'0'); /* accumulate a digit */ } else { ++lo[0]; /* too many digits, just scale exponent */ } ++s; seen = 1; } if (*s == btowc(localeconv()->decimal_point[0])) { ++s; } if (nsig == 0) { while (*s == L'0') { --lo[0]; /* scale for stripped zeros after point */ ++s; seen = 1; } } while (iswdigit(*s)) { if (nsig <= maxsig) { /* accumulate a fraction digit */ buf[nsig++] = (char)(*s - L'0'); --lo[0]; } ++s; seen = 1; } if (maxsig < nsig) { /* discard excess digit after rounding up */ unsigned int ms = maxsig; /* to quiet warnings */ if (BASE / 2 <= buf[ms]) { ++buf[ms - 1]; /* okay if digit becomes BASE */ } nsig = maxsig; ++lo[0]; } for (; 0 < nsig && buf[nsig - 1] == '\0'; --nsig) { ++lo[0]; /* discard trailing zeros */ } if (nsig == 0) { buf[nsig++] = '\0'; /* ensure at least one digit */ } if (seen) { /* convert digit sequence to words */ int bufidx = 0; /* next digit in buffer */ int wordidx = NDIG - nsig % NDIG; /* next digit in word (% NDIG) */ word = wordidx % NDIG == 0 ? 0 : 1; for (; bufidx < nsig; ++wordidx, ++bufidx) { if (wordidx % NDIG == 0) { lo[++word] = buf[bufidx]; } else { lo[word] = lo[word] * BASE + buf[bufidx]; } } if (*s == L'e' || *s == L'E') { /* parse exponent */ const wchar_t *ssav = s; const wchar_t esign = *++s == L'+' || *s == L'-' ? *s++ : L'+'; int eseen = 0; long lexp = 0; for (; iswdigit(*s); ++s, eseen = 1) { if (lexp < 100000000) /* else overflow */ { lexp = lexp * 10 + *s - L'0'; } } if (esign == L'-') { lexp = -lexp; } lo[0] += lexp; if (!eseen) { s = ssav; /* roll back if incomplete exponent */ } } } if (!seen) { word = 0; /* return zero if bad parse */ } if (endptr) { *endptr = (wchar_t *)(seen ? s : s0); /* roll back if bad parse */ } return (word); }
SEXP countfields(SEXP args) { SEXP ans, file, sep, bns, quotes, comstr; int nfields, nskip, i, c, inquote, quote = 0; int blocksize, nlines, blskip; const char *p; Rboolean dbcslocale = (MB_CUR_MAX == 2); LocalData data = {NULL, 0, 0, '.', NULL, NO_COMCHAR, 0, NULL, FALSE, FALSE, 0, FALSE, FALSE}; data.NAstrings = R_NilValue; args = CDR(args); file = CAR(args); args = CDR(args); sep = CAR(args); args = CDR(args); quotes = CAR(args); args = CDR(args); nskip = asInteger(CAR(args)); args = CDR(args); blskip = asLogical(CAR(args)); args = CDR(args); comstr = CAR(args); if (TYPEOF(comstr) != STRSXP || length(comstr) != 1) error(_("invalid '%s' argument"), "comment.char"); p = translateChar(STRING_ELT(comstr, 0)); data.comchar = NO_COMCHAR; /* here for -Wall */ if (strlen(p) > 1) error(_("invalid '%s' argument"), "comment.char"); else if (strlen(p) == 1) data.comchar = (unsigned char)*p; if (nskip < 0 || nskip == NA_INTEGER) nskip = 0; if (blskip == NA_LOGICAL) blskip = 1; if (isString(sep) || isNull(sep)) { if (length(sep) == 0) data.sepchar = 0; else data.sepchar = (unsigned char) translateChar(STRING_ELT(sep, 0))[0]; /* gets compared to chars: bug prior to 1.7.0 */ } else error(_("invalid '%s' argument"), "sep"); if (isString(quotes)) { const char *sc = translateChar(STRING_ELT(quotes, 0)); if (strlen(sc)) data.quoteset = strdup(sc); else data.quoteset = ""; } else if (isNull(quotes)) data.quoteset = ""; else error(_("invalid quote symbol set")); i = asInteger(file); data.con = getConnection(i); if(i == 0) { data.ttyflag = 1; } else { data.ttyflag = 0; data.wasopen = data.con->isopen; if(!data.wasopen) { strcpy(data.con->mode, "r"); if(!data.con->open(data.con)) error(_("cannot open the connection")); if(!data.con->canread) { data.con->close(data.con); error(_("cannot read from this connection")); } } else { if(!data.con->canread) error(_("cannot read from this connection")); } for (i = 0; i < nskip; i++) /* MBCS-safe */ while ((c = scanchar(FALSE, &data)) != '\n' && c != R_EOF); } blocksize = SCAN_BLOCKSIZE; PROTECT(ans = allocVector(INTSXP, blocksize)); nlines = 0; nfields = 0; inquote = 0; data.save = 0; for (;;) { c = scanchar(inquote, &data); if (c == R_EOF) { if (nfields != 0) INTEGER(ans)[nlines] = nfields; else nlines--; goto donecf; } else if (c == '\n') { if (nfields || !blskip) { INTEGER(ans)[nlines] = nfields; nlines++; nfields = 0; inquote = 0; } if (nlines == blocksize) { bns = ans; blocksize = 2 * blocksize; ans = allocVector(INTSXP, blocksize); UNPROTECT(1); PROTECT(ans); copyVector(ans, bns); } continue; } else if (data.sepchar) { if (nfields == 0) nfields++; if (inquote && (c == R_EOF || c == '\n')) { if(!data.wasopen) data.con->close(data.con); error(_("string terminated by newline or EOF")); } if (inquote && c == quote) inquote = 0; else if (strchr(data.quoteset, c)) { inquote = 1; quote = c; } if (c == data.sepchar && !inquote) nfields++; } else if (!Rspace(c)) { if (strchr(data.quoteset, c)) { quote = c; inquote = 1; while ((c = scanchar(inquote, &data)) != quote) { if (c == R_EOF || c == '\n') { if(!data.wasopen) data.con->close(data.con); error(_("string terminated by newline or EOF")); } } inquote = 0; } else { do { if(dbcslocale && btowc(c) == WEOF) scanchar2(&data); c = scanchar(FALSE, &data); } while (!Rspace(c) && c != R_EOF); if (c == R_EOF) c = '\n'; unscanchar(c, &data); } nfields++; } } donecf: /* we might have a character that was unscanchar-ed. So pushback if possible */ if (data.save && !data.ttyflag && data.wasopen) { char line[2] = " "; line[0] = (char) data.save; con_pushback(data.con, FALSE, line); } if(!data.wasopen) data.con->close(data.con); if (nlines < 0) { UNPROTECT(1); return R_NilValue; } if (nlines == blocksize) { UNPROTECT(1); return ans; } bns = allocVector(INTSXP, nlines+1); for (i = 0; i <= nlines; i++) INTEGER(bns)[i] = INTEGER(ans)[i]; UNPROTECT(1); if (data.quoteset[0]) free(data.quoteset); return bns; }
wint_t _Locale_btowc(struct _Locale_ctype *l, int c) { return btowc(c); }
/* * Allocate and read a binary string from file. * The strings are nl-ended or zero-ended, depending on the sort setting. */ struct bwstring * bwsfgetln(FILE *f, size_t *len, bool zero_ended, struct reader_buffer *rb) { wint_t eols; eols = zero_ended ? btowc('\0') : btowc('\n'); if (!zero_ended && (MB_CUR_MAX > 1)) { wchar_t *ret; ret = fgetwln(f, len); if (ret == NULL) { if (!feof(f)) err(2, NULL); return (NULL); } if (*len > 0) { if (ret[*len - 1] == (wchar_t)eols) --(*len); } return (bwssbdup(ret, *len)); } else if (!zero_ended && (MB_CUR_MAX == 1)) { char *ret; ret = fgetln(f, len); if (ret == NULL) { if (!feof(f)) err(2, NULL); return (NULL); } if (*len > 0) { if (ret[*len - 1] == '\n') --(*len); } return (bwscsbdup((unsigned char*)ret, *len)); } else { *len = 0; if (feof(f)) return (NULL); if (2 >= rb->fgetwln_z_buffer_size) { rb->fgetwln_z_buffer_size += 256; rb->fgetwln_z_buffer = sort_realloc(rb->fgetwln_z_buffer, sizeof(wchar_t) * rb->fgetwln_z_buffer_size); } rb->fgetwln_z_buffer[*len] = 0; if (MB_CUR_MAX == 1) while (!feof(f)) { int c; c = fgetc(f); if (c == EOF) { if (*len == 0) return (NULL); goto line_read_done; } if (c == eols) goto line_read_done; if (*len + 1 >= rb->fgetwln_z_buffer_size) { rb->fgetwln_z_buffer_size += 256; rb->fgetwln_z_buffer = sort_realloc(rb->fgetwln_z_buffer, SIZEOF_WCHAR_STRING(rb->fgetwln_z_buffer_size)); } rb->fgetwln_z_buffer[*len] = c; rb->fgetwln_z_buffer[++(*len)] = 0; } else while (!feof(f)) { wint_t c = 0; c = fgetwc(f); if (c == WEOF) { if (*len == 0) return (NULL); goto line_read_done; } if (c == eols) goto line_read_done; if (*len + 1 >= rb->fgetwln_z_buffer_size) { rb->fgetwln_z_buffer_size += 256; rb->fgetwln_z_buffer = sort_realloc(rb->fgetwln_z_buffer, SIZEOF_WCHAR_STRING(rb->fgetwln_z_buffer_size)); } rb->fgetwln_z_buffer[*len] = c; rb->fgetwln_z_buffer[++(*len)] = 0; } line_read_done: /* we do not count the last 0 */ return (bwssbdup(rb->fgetwln_z_buffer, *len)); } }
/* * _cursesi_addwchar - * Internal function to add a wide character and update the row * and column positions. */ int _cursesi_addwchar(WINDOW *win, __LINE **lnp, int *y, int *x, const cchar_t *wch) { #ifndef HAVE_WCHAR return (ERR); #else int sx = 0, ex = 0, cw = 0, i = 0, newx = 0; __LDATA *lp = &win->alines[*y]->line[*x], *tp = NULL; nschar_t *np = NULL; cchar_t cc; attr_t attributes; /* special characters handling */ switch (wch->vals[0]) { case L'\b': if (--*x < 0) *x = 0; win->curx = *x; return OK; case L'\r': *x = 0; return OK; case L'\n': wclrtoeol(win); PSYNCH_IN; *x = 0; (*lnp)->flags &= ~__ISPASTEOL; if (*y == win->scr_b) { if (!(win->flags & __SCROLLOK)) return ERR; PSYNCH_OUT; scroll(win); PSYNCH_IN; } else { (*y)++; } PSYNCH_OUT; return OK; case L'\t': cc.vals[0] = L' '; cc.elements = 1; cc.attributes = win->wattr; for (i = 0; i < 8 - (*x % 8); i++) { if (wadd_wch(win, &cc) == ERR) return ERR; } return OK; } /* check for non-spacing character */ if (!wcwidth(wch->vals[0])) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: char '%c' is non-spacing\n", wch->vals[0]); #endif /* DEBUG */ cw = WCOL(*lp); if (cw < 0) { lp += cw; *x += cw; } for (i = 0; i < wch->elements; i++) { if (!(np = (nschar_t *) malloc(sizeof(nschar_t)))) return ERR;; np->ch = wch->vals[i]; np->next = lp->nsp; lp->nsp = np; } (*lnp)->flags |= __ISDIRTY; newx = *x + win->ch_off; if (newx < *(*lnp)->firstchp) *(*lnp)->firstchp = newx; if (newx > *(*lnp)->lastchp) *(*lnp)->lastchp = newx; __touchline(win, *y, *x, *x); return OK; } /* check for new line first */ if ((*lnp)->flags & __ISPASTEOL) { *x = 0; (*lnp)->flags &= ~__ISPASTEOL; if (*y == win->scr_b) { if (!(win->flags & __SCROLLOK)) return ERR; PSYNCH_OUT; scroll(win); PSYNCH_IN; } else { (*y)++; } (*lnp) = win->alines[*y]; lp = &win->alines[*y]->line[*x]; } /* clear out the current character */ cw = WCOL(*lp); if (cw >= 0) { sx = *x; } else { for (sx = *x - 1; sx >= max(*x + cw, 0); sx--) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: clear current char (%d,%d)\n", *y, sx); #endif /* DEBUG */ tp = &win->alines[*y]->line[sx]; tp->ch = (wchar_t) btowc((int) win->bch); if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) return ERR; tp->attr = win->battr; SET_WCOL(*tp, 1); } sx = *x + cw; (*lnp)->flags |= __ISDIRTY; newx = sx + win->ch_off; if (newx < *(*lnp)->firstchp) *(*lnp)->firstchp = newx; } /* check for enough space before the end of line */ cw = wcwidth(wch->vals[0]); if (cw < 0) cw = 1; if (cw > win->maxx - *x) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: clear EOL (%d,%d)\n", *y, *x); #endif /* DEBUG */ (*lnp)->flags |= __ISDIRTY; newx = *x + win->ch_off; if (newx < *(*lnp)->firstchp) *(*lnp)->firstchp = newx; for (tp = lp; *x < win->maxx; tp++, (*x)++) { tp->ch = (wchar_t) btowc((int) win->bch); if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) return ERR; tp->attr = win->battr; SET_WCOL(*tp, 1); } newx = win->maxx - 1 + win->ch_off; if (newx > *(*lnp)->lastchp) *(*lnp)->lastchp = newx; __touchline(win, *y, sx, (int) win->maxx - 1); sx = *x = 0; if (*y == win->scr_b) { if (!(win->flags & __SCROLLOK)) return ERR; PSYNCH_OUT; scroll(win); PSYNCH_IN; } else { (*y)++; } lp = &win->alines[*y]->line[0]; (*lnp) = win->alines[*y]; } win->cury = *y; /* add spacing character */ #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add character (%d,%d) 0x%x\n", *y, *x, wch->vals[0]); #endif /* DEBUG */ (*lnp)->flags |= __ISDIRTY; newx = *x + win->ch_off; if (newx < *(*lnp)->firstchp) *(*lnp)->firstchp = newx; if (lp->nsp) { __cursesi_free_nsp(lp->nsp); lp->nsp = NULL; } lp->ch = wch->vals[0]; attributes = (win->wattr | wch->attributes) & (WA_ATTRIBUTES & ~__COLOR); if (wch->attributes & __COLOR) attributes |= wch->attributes & __COLOR; else if (win->wattr & __COLOR) attributes |= win->wattr & __COLOR; if (attributes & __COLOR) lp->attr = attributes | (win->battr & ~__COLOR); else lp->attr = attributes | win->battr; SET_WCOL(*lp, cw); #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add spacing char 0x%x, attr 0x%x\n", lp->ch, lp->attr); #endif /* DEBUG */ if (wch->elements > 1) { for (i = 1; i < wch->elements; i++) { np = (nschar_t *)malloc(sizeof(nschar_t)); if (!np) return ERR;; np->ch = wch->vals[i]; np->next = lp->nsp; #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add non-spacing char 0x%x\n", np->ch); #endif /* DEBUG */ lp->nsp = np; } } #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: non-spacing list header: %p\n", lp->nsp); __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: add rest columns (%d:%d)\n", sx + 1, sx + cw - 1); #endif /* DEBUG */ for (tp = lp + 1, *x = sx + 1; *x - sx <= cw - 1; tp++, (*x)++) { if (tp->nsp) { __cursesi_free_nsp(tp->nsp); tp->nsp = NULL; } tp->ch = wch->vals[0]; tp->attr = lp->attr & WA_ATTRIBUTES; /* Mark as "continuation" cell */ tp->attr |= __WCWIDTH; } if (*x == win->maxx) { (*lnp)->flags |= __ISPASTEOL; newx = win->maxx - 1 + win->ch_off; if (newx > *(*lnp)->lastchp) *(*lnp)->lastchp = newx; __touchline(win, *y, sx, (int) win->maxx - 1); win->curx = sx; } else { win->curx = *x; /* clear the remining of the current characer */ if (*x && *x < win->maxx) { ex = sx + cw; tp = &win->alines[*y]->line[ex]; while (ex < win->maxx && WCOL(*tp) < 0) { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "_cursesi_addwchar: clear " "remaining of current char (%d,%d)nn", *y, ex); #endif /* DEBUG */ tp->ch = (wchar_t) btowc((int) win->bch); if (_cursesi_copy_nsp(win->bnsp, tp) == ERR) return ERR; tp->attr = win->battr; SET_WCOL(*tp, 1); tp++, ex++; } newx = ex - 1 + win->ch_off; if (newx > *(*lnp)->lastchp) *(*lnp)->lastchp = newx; __touchline(win, *y, sx, ex - 1); } } #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "add_wch: %d : 0x%x\n", lp->ch, lp->attr); #endif /* DEBUG */ return OK; #endif }
/* * __wgetn_wstr -- * The actual implementation. * Note that we include a trailing L'\0' for safety, so str will contain * at most n - 1 other characters. */ int __wgetn_wstr(WINDOW *win, wchar_t *wstr, int n) { wchar_t *ostr, ec, kc, sc[ 2 ]; int oldx, remain; wint_t wc; cchar_t cc; ostr = wstr; if ( erasewchar( &ec ) == ERR ) return ERR; if ( killwchar( &kc ) == ERR ) return ERR; sc[ 0 ] = ( wchar_t )btowc( ' ' ); sc[ 1 ] = L'\0'; setcchar( &cc, sc, win->wattr, 0, NULL ); oldx = win->curx; remain = n - 1; while (wget_wch(win, &wc) != ERR && wc != L'\n' && wc != L'\r') { #ifdef DEBUG __CTRACE(__CTRACE_INPUT, "__wgetn_wstr: win %p, char 0x%x, remain %d\n", win, wc, remain); #endif *wstr = wc; touchline(win, win->cury, 1); if (wc == ec || wc == KEY_BACKSPACE || wc == KEY_LEFT) { *wstr = L'\0'; if (wstr != ostr) { if ((wchar_t)wc == ec) { mvwadd_wch(win, win->cury, win->curx, &cc); wmove(win, win->cury, win->curx - 1); } if (wc == KEY_BACKSPACE || wc == KEY_LEFT) { /* getch() displays the key sequence */ mvwadd_wch(win, win->cury, win->curx - 1, &cc); mvwadd_wch(win, win->cury, win->curx - 2, &cc); wmove(win, win->cury, win->curx - 1); } wstr--; if (n != -1) { /* We're counting chars */ remain++; } } else { /* str == ostr */ if (wc == KEY_BACKSPACE || wc == KEY_LEFT) /* getch() displays the other keys */ mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, oldx); } } else if (wc == kc) { *wstr = L'\0'; if (wstr != ostr) { /* getch() displays the kill character */ mvwadd_wch(win, win->cury, win->curx - 1, &cc); /* Clear the characters from screen and str */ while (wstr != ostr) { mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, win->curx - 1); wstr--; if (n != -1) /* We're counting chars */ remain++; } mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, win->curx - 1); } else /* getch() displays the kill character */ mvwadd_wch( win, win->cury, oldx, &cc ); wmove(win, win->cury, oldx); } else if (wc >= KEY_MIN && wc <= KEY_MAX) { /* get_wch() displays these characters */ mvwadd_wch( win, win->cury, win->curx - 1, &cc ); wmove(win, win->cury, win->curx - 1); } else { if (remain) { wstr++; remain--; } else { mvwadd_wch(win, win->cury, win->curx - 1, &cc); wmove(win, win->cury, win->curx - 1); } } } if (wc == ERR) { *wstr = L'\0'; return ERR; } *wstr = L'\0'; return OK; }
/** * Read user input. * * @param prompt Prompt * @return The read line (dynamically allocated) or NULL */ char * readline(const char *prompt) { char *out; const int sleep_time_milliseconds = 90; volatile struct readline_session_context *ctx; wchar_t *buf_p = &g_push_back_buf[0]; ctx = new_session(prompt); if (setjmp(g_readline_loc_info) != 0) { session_destroy(ctx); mutex_unlock(&g_puts_mutex); return NULL; } g_readline_loop = true; g_resize_requested = false; g_hist_next = false; g_hist_prev = false; mutex_lock(&g_puts_mutex); write_cmdprompt(ctx->act, ctx->prompt, ctx->prompt_size); mutex_unlock(&g_puts_mutex); do { wint_t wc; ctx->insert_mode = (ctx->bufpos != ctx->n_insert); ctx->no_bufspc = (ctx->n_insert + 1 >= readline_buffersize); if (*buf_p) { wc = *buf_p++; } else if (wget_wch(ctx->act, &wc) == ERR) { (void) napms(sleep_time_milliseconds); continue; } mutex_lock(&g_puts_mutex); switch (wc) { case CTRL_A: while (ctx->bufpos != 0) { case_key_left(ctx); ctx->insert_mode = (ctx->bufpos != ctx->n_insert); } break; case CTRL_E: while (ctx->insert_mode) { case_key_right(ctx); ctx->insert_mode = (ctx->bufpos != ctx->n_insert); } break; case MY_KEY_DLE: window_select_prev(); break; /* CTRL+P */ case MY_KEY_SO: window_select_next(); break; /* CTRL+N */ case KEY_DOWN: g_hist_next = true; session_destroy(ctx); mutex_unlock(&g_puts_mutex); return NULL; case KEY_UP: g_hist_prev = true; session_destroy(ctx); mutex_unlock(&g_puts_mutex); return NULL; case KEY_LEFT: case MY_KEY_STX: case_key_left(ctx); break; case KEY_RIGHT: case MY_KEY_ACK: case_key_right(ctx); break; case KEY_BACKSPACE: case MY_KEY_BS: case_key_backspace(ctx); break; case KEY_F(5): case BLINK: handle_key(ctx, btowc(BLINK)); break; case KEY_F(6): case BOLD_ALIAS: handle_key(ctx, btowc(BOLD)); break; case KEY_F(7): case COLOR: handle_key(ctx, btowc(COLOR)); break; case KEY_F(8): case NORMAL: handle_key(ctx, btowc(NORMAL)); break; case KEY_F(9): case REVERSE: handle_key(ctx, btowc(REVERSE)); break; case KEY_F(10): case UNDERLINE: handle_key(ctx, btowc(UNDERLINE)); break; case KEY_F(11): cmd_close(""); break; case KEY_F(12): window_close_all_priv_conv(); break; case KEY_DC: case MY_KEY_EOT: case_key_dc(ctx); break; case KEY_NPAGE: window_scroll_down(g_active_window); break; case KEY_PPAGE: window_scroll_up(g_active_window); break; case '\t': break; case '\n': case KEY_ENTER: case WINDOWS_KEY_ENTER: g_readline_loop = false; break; case KEY_RESIZE: case MY_KEY_RESIZE: g_resize_requested = true; /*FALLTHROUGH*/ case '\a': session_destroy(ctx); mutex_unlock(&g_puts_mutex); return NULL; default: if (iswprint(wc)) { handle_key(ctx, wc); } break; } mutex_unlock(&g_puts_mutex); } while (g_readline_loop); if (ctx->n_insert > 0) { ctx->buffer[ctx->n_insert] = 0L; } else { session_destroy(ctx); return NULL; } mutex_lock(&g_puts_mutex); write_cmdprompt(ctx->act, "", 0); mutex_unlock(&g_puts_mutex); out = finalize_out_string(ctx->buffer); session_destroy(ctx); return out; }