1/**************************************************************************** 2 * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. * 3 * * 4 * Permission is hereby granted, free of charge, to any person obtaining a * 5 * copy of this software and associated documentation files (the * 6 * "Software"), to deal in the Software without restriction, including * 7 * without limitation the rights to use, copy, modify, merge, publish, * 8 * distribute, distribute with modifications, sublicense, and/or sell * 9 * copies of the Software, and to permit persons to whom the Software is * 10 * furnished to do so, subject to the following conditions: * 11 * * 12 * The above copyright notice and this permission notice shall be included * 13 * in all copies or substantial portions of the Software. * 14 * * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 18 * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 21 * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 22 * * 23 * Except as contained in this notice, the name(s) of the above copyright * 24 * holders shall not be used in advertising or otherwise to promote the * 25 * sale, use or other dealings in this Software without prior written * 26 * authorization. * 27 ****************************************************************************/ 28 29/**************************************************************************** 30 * Author: Juergen Pfeifer, 1995,1997 * 31 ****************************************************************************/ 32 33/*************************************************************************** 34* Module m_item_new * 35* Create and destroy menu items * 36* Set and get marker string for menu * 37***************************************************************************/ 38 39#include "menu.priv.h" 40 41#if USE_WIDEC_SUPPORT 42#include <wctype.h> 43#endif 44 45MODULE_ID("$Id: m_item_new.c,v 1.25 2005/04/16 22:24:38 tom Exp $") 46 47/*--------------------------------------------------------------------------- 48| Facility : libnmenu 49| Function : bool Is_Printable_String(const char *s) 50| 51| Description : Checks whether or not the string contains only printable 52| characters. 53| 54| Return Values : TRUE - if string is printable 55| FALSE - if string contains non-printable characters 56+--------------------------------------------------------------------------*/ 57static bool 58Is_Printable_String(const char *s) 59{ 60 int result = TRUE; 61 62#if USE_WIDEC_SUPPORT 63 int count = mbstowcs(0, s, 0); 64 wchar_t *temp = 0; 65 66 assert(s); 67 68 if (count > 0 69 && (temp = typeCalloc(wchar_t, (2 + count))) != 0) 70 { 71 int n; 72 73 mbstowcs(temp, s, (unsigned)count); 74 for (n = 0; n < count; ++n) 75 if (!iswprint(temp[n])) 76 { 77 result = FALSE; 78 break; 79 } 80 free(temp); 81 } 82#else 83 assert(s); 84 while (*s) 85 { 86 if (!isprint(UChar(*s))) 87 { 88 result = FALSE; 89 break; 90 } 91 s++; 92 } 93#endif 94 return result; 95} 96 97/*--------------------------------------------------------------------------- 98| Facility : libnmenu 99| Function : ITEM *new_item(char *name, char *description) 100| 101| Description : Create a new item with name and description. Return 102| a pointer to this new item. 103| N.B.: an item must(!) have a name. 104| 105| Return Values : The item pointer or NULL if creation failed. 106+--------------------------------------------------------------------------*/ 107NCURSES_EXPORT(ITEM *) 108new_item(const char *name, const char *description) 109{ 110 ITEM *item; 111 112 T((T_CALLED("new_item(\"%s\", \"%s\")"), 113 name ? name : "", 114 description ? description : "")); 115 116 if (!name || (*name == '\0') || !Is_Printable_String(name)) 117 { 118 item = (ITEM *) 0; 119 SET_ERROR(E_BAD_ARGUMENT); 120 } 121 else 122 { 123 item = (ITEM *) calloc(1, sizeof(ITEM)); 124 if (item) 125 { 126 *item = _nc_Default_Item; /* hope we have struct assignment */ 127 128 item->name.length = strlen(name); 129 item->name.str = name; 130 131 if (description && (*description != '\0') && 132 Is_Printable_String(description)) 133 { 134 item->description.length = strlen(description); 135 item->description.str = description; 136 } 137 else 138 { 139 item->description.length = 0; 140 item->description.str = (char *)0; 141 } 142 } 143 else 144 SET_ERROR(E_SYSTEM_ERROR); 145 } 146 returnItem(item); 147} 148 149/*--------------------------------------------------------------------------- 150| Facility : libnmenu 151| Function : int free_item(ITEM *item) 152| 153| Description : Free the allocated storage for this item. 154| N.B.: a connected item can't be freed. 155| 156| Return Values : E_OK - success 157| E_BAD_ARGUMENT - invalid value has been passed 158| E_CONNECTED - item is still connected to a menu 159+--------------------------------------------------------------------------*/ 160NCURSES_EXPORT(int) 161free_item(ITEM * item) 162{ 163 T((T_CALLED("free_item(%p)"), item)); 164 165 if (!item) 166 RETURN(E_BAD_ARGUMENT); 167 168 if (item->imenu) 169 RETURN(E_CONNECTED); 170 171 free(item); 172 173 RETURN(E_OK); 174} 175 176/*--------------------------------------------------------------------------- 177| Facility : libnmenu 178| Function : int set_menu_mark( MENU *menu, const char *mark ) 179| 180| Description : Set the mark string used to indicate the current 181| item (single-valued menu) or the selected items 182| (multi-valued menu). 183| The mark argument may be NULL, in which case no 184| marker is used. 185| This might be a little bit tricky, because this may 186| affect the geometry of the menu, which we don't allow 187| if it is already posted. 188| 189| Return Values : E_OK - success 190| E_BAD_ARGUMENT - an invalid value has been passed 191| E_SYSTEM_ERROR - no memory to store mark 192+--------------------------------------------------------------------------*/ 193NCURSES_EXPORT(int) 194set_menu_mark(MENU * menu, const char *mark) 195{ 196 unsigned l; 197 198 T((T_CALLED("set_menu_mark(%p,%s)"), menu, _nc_visbuf(mark))); 199 200 if (mark && (*mark != '\0') && Is_Printable_String(mark)) 201 l = strlen(mark); 202 else 203 l = 0; 204 205 if (menu) 206 { 207 char *old_mark = menu->mark; 208 unsigned short old_status = menu->status; 209 210 if (menu->status & _POSTED) 211 { 212 /* If the menu is already posted, the geometry is fixed. Then 213 we can only accept a mark with exactly the same length */ 214 if (menu->marklen != (int)l) 215 RETURN(E_BAD_ARGUMENT); 216 } 217 menu->marklen = l; 218 if (l) 219 { 220 menu->mark = (char *)malloc(l + 1); 221 if (menu->mark) 222 { 223 strcpy(menu->mark, mark); 224 if (menu != &_nc_Default_Menu) 225 menu->status |= _MARK_ALLOCATED; 226 } 227 else 228 { 229 menu->mark = old_mark; 230 RETURN(E_SYSTEM_ERROR); 231 } 232 } 233 else 234 menu->mark = (char *)0; 235 236 if ((old_status & _MARK_ALLOCATED) && old_mark) 237 free(old_mark); 238 239 if (menu->status & _POSTED) 240 { 241 _nc_Draw_Menu(menu); 242 _nc_Show_Menu(menu); 243 } 244 else 245 { 246 /* Recalculate the geometry */ 247 _nc_Calculate_Item_Length_and_Width(menu); 248 } 249 } 250 else 251 { 252 returnCode(set_menu_mark(&_nc_Default_Menu, mark)); 253 } 254 RETURN(E_OK); 255} 256 257/*--------------------------------------------------------------------------- 258| Facility : libnmenu 259| Function : char *menu_mark(const MENU *menu) 260| 261| Description : Return a pointer to the marker string 262| 263| Return Values : The marker string pointer or NULL if no marker defined 264+--------------------------------------------------------------------------*/ 265NCURSES_EXPORT(const char *) 266menu_mark(const MENU * menu) 267{ 268 T((T_CALLED("menu_mark(%p)"), menu)); 269 returnPtr(Normalize_Menu(menu)->mark); 270} 271 272/* m_item_new.c */ 273