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