diff options
Diffstat (limited to 'lib/libcurses/base/lib_slkset.c')
-rw-r--r-- | lib/libcurses/base/lib_slkset.c | 113 |
1 files changed, 83 insertions, 30 deletions
diff --git a/lib/libcurses/base/lib_slkset.c b/lib/libcurses/base/lib_slkset.c index a8360d60f49..6958f8d2a9a 100644 --- a/lib/libcurses/base/lib_slkset.c +++ b/lib/libcurses/base/lib_slkset.c @@ -1,7 +1,7 @@ -/* $OpenBSD: lib_slkset.c,v 1.3 2001/01/22 18:05:43 millert Exp $ */ +/* $OpenBSD: lib_slkset.c,v 1.4 2010/01/12 23:22:06 nicm Exp $ */ /**************************************************************************** - * Copyright (c) 1998,2000 Free Software Foundation, Inc. * + * Copyright (c) 1998-2005,2007 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -29,8 +29,8 @@ ****************************************************************************/ /**************************************************************************** - * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * - * and: Eric S. Raymond <esr@snark.thyrsus.com> * + * Author: Juergen Pfeifer * + * and: Thomas E. Dickey * ****************************************************************************/ /* @@ -40,59 +40,112 @@ #include <curses.priv.h> #include <ctype.h> -MODULE_ID("$From: lib_slkset.c,v 1.6 2000/12/10 02:43:27 tom Exp $") +#if USE_WIDEC_SUPPORT +#if HAVE_WCTYPE_H +#include <wctype.h> +#endif +#endif + +MODULE_ID("$Id: lib_slkset.c,v 1.4 2010/01/12 23:22:06 nicm Exp $") NCURSES_EXPORT(int) slk_set(int i, const char *astr, int format) { - SLK *slk = SP->_slk; - size_t len; + SLK *slk; + int offset; + int numchrs; + int numcols; + int limit; const char *str = astr; const char *p; T((T_CALLED("slk_set(%d, \"%s\", %d)"), i, str, format)); - if (slk == NULL || i < 1 || i > slk->labcnt || format < 0 || format > 2) + if (SP == 0 + || (slk = SP->_slk) == 0 + || i < 1 + || i > slk->labcnt + || format < 0 + || format > 2) returnCode(ERR); if (str == NULL) str = ""; + --i; /* Adjust numbering of labels */ - while (isspace(CharOf(*str))) + limit = MAX_SKEY_LEN(SP->slk_format); + while (isspace(UChar(*str))) str++; /* skip over leading spaces */ p = str; - while (isprint(CharOf(*p))) + +#if USE_WIDEC_SUPPORT + numcols = 0; + while (*p != 0) { + mbstate_t state; + wchar_t wc; + size_t need; + + init_mb(state); + need = mbrtowc(0, p, strlen(p), &state); + if (need == (size_t) -1) + break; + mbrtowc(&wc, p, need, &state); + if (!iswprint((wint_t) wc)) + break; + if (wcwidth(wc) + numcols > limit) + break; + numcols += wcwidth(wc); + p += need; + } + numchrs = (p - str); +#else + while (isprint(UChar(*p))) p++; /* The first non-print stops */ - --i; /* Adjust numbering of labels */ + numcols = (p - str); + if (numcols > limit) + numcols = limit; + numchrs = numcols; +#endif - len = (size_t) (p - str); - if (len > (unsigned) slk->maxlen) - len = slk->maxlen; - if (len == 0) - slk->ent[i].text[0] = 0; - else - (void) strlcpy(slk->ent[i].text, str, len+1); - memset(slk->ent[i].form_text, ' ', (unsigned) slk->maxlen); - /* len = strlen(slk->ent[i].text); */ + FreeIfNeeded(slk->ent[i].ent_text); + if ((slk->ent[i].ent_text = strdup(str)) == 0) + returnCode(ERR); + slk->ent[i].ent_text[numchrs] = '\0'; + + if ((slk->ent[i].form_text = (char *) _nc_doalloc(slk->ent[i].form_text, + (unsigned) (limit + + numchrs + 1)) + ) == 0) + returnCode(ERR); switch (format) { + default: case 0: /* left-justified */ - memcpy(slk->ent[i].form_text, - slk->ent[i].text, - len); + offset = 0; break; case 1: /* centered */ - memcpy(slk->ent[i].form_text + (slk->maxlen - len) / 2, - slk->ent[i].text, - len); + offset = (limit - numcols) / 2; break; case 2: /* right-justified */ - memcpy(slk->ent[i].form_text + slk->maxlen - len, - slk->ent[i].text, - len); + offset = limit - numcols; break; } - slk->ent[i].form_text[slk->maxlen] = 0; + if (offset <= 0) + offset = 0; + else + memset(slk->ent[i].form_text, ' ', (unsigned) offset); + + memcpy(slk->ent[i].form_text + offset, + slk->ent[i].ent_text, + (unsigned) numchrs); + + if (offset < limit) { + memset(slk->ent[i].form_text + offset + numchrs, + ' ', + (unsigned) (limit - (offset + numcols))); + } + + slk->ent[i].form_text[numchrs - numcols + limit] = 0; slk->ent[i].dirty = TRUE; returnCode(OK); } |