X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Fbase%2Flib_slkset.c;h=9379b36322e2a12ddbbe4b64ef47b7d7d0b92263;hp=27471add77fa97c3f07788f654f34305b1b4b815;hb=2639531af0c3ca25b48e7bcb9c790fa566cc5892;hpb=0eb88fc5281804773e2a0c7a488a4452463535ce diff --git a/ncurses/base/lib_slkset.c b/ncurses/base/lib_slkset.c index 27471add..9379b363 100644 --- a/ncurses/base/lib_slkset.c +++ b/ncurses/base/lib_slkset.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998 Free Software Foundation, Inc. * + * Copyright (c) 1998-2004,2005 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 * @@ -27,8 +27,8 @@ ****************************************************************************/ /**************************************************************************** - * Author: Zeyd M. Ben-Halim 1992,1995 * - * and: Eric S. Raymond * + * Author: Juergen Pfeifer * + * and: Thomas E. Dickey * ****************************************************************************/ /* @@ -38,58 +38,107 @@ #include #include -MODULE_ID("$Id: lib_slkset.c,v 1.3 1998/02/11 12:13:56 tom Exp $") +#if USE_WIDEC_SUPPORT +#if HAVE_WCTYPE_H +#include +#endif +#endif -int +MODULE_ID("$Id: lib_slkset.c,v 1.16 2006/12/17 19:47:09 tom Exp $") + +NCURSES_EXPORT(int) slk_set(int i, const char *astr, int format) { -SLK *slk = SP->_slk; -size_t len; -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) - returnCode(ERR); - if (str == NULL) - str = ""; - - while (isspace(*str)) str++; /* skip over leading spaces */ - p = str; - while (isprint(*p)) p++; /* The first non-print stops */ - - --i; /* Adjust numbering of labels */ - - len = (size_t)(p - str); - if (len > (unsigned)slk->maxlen) - len = slk->maxlen; - if (len==0) - slk->ent[i].text[0] = 0; - else - (void) strncpy(slk->ent[i].text, str, len); - memset(slk->ent[i].form_text,' ', (unsigned)slk->maxlen); - slk->ent[i].text[slk->maxlen] = 0; - /* len = strlen(slk->ent[i].text); */ - - switch(format) { - case 0: /* left-justified */ - memcpy(slk->ent[i].form_text, - slk->ent[i].text, - len); - break; - case 1: /* centered */ - memcpy(slk->ent[i].form_text+(slk->maxlen - len)/2, - slk->ent[i].text, - len); - break; - case 2: /* right-justified */ - memcpy(slk->ent[i].form_text+ slk->maxlen - len, - slk->ent[i].text, - len); - break; - } - slk->ent[i].form_text[slk->maxlen] = 0; - slk->ent[i].dirty = TRUE; - returnCode(OK); + SLK *slk = SP->_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) + returnCode(ERR); + if (str == NULL) + str = ""; + --i; /* Adjust numbering of labels */ + + limit = MAX_SKEY_LEN(SP->slk_format); + while (isspace(UChar(*str))) + str++; /* skip over leading spaces */ + p = str; + +#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 */ + + numcols = (p - str); + if (numcols > limit) + numcols = limit; + numchrs = numcols; +#endif + + 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 */ + offset = 0; + break; + case 1: /* centered */ + offset = (limit - numcols) / 2; + break; + case 2: /* right-justified */ + offset = limit - numcols; + break; + } + 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); }