]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - menu/m_item_new.c
ncurses 6.2 - patch 20201227
[ncurses.git] / menu / m_item_new.c
index 0d0e98441b8897bc29655c2c8fae1bdbcd566241..1e6130e678e2426d36ef7fb099f6d819862aad1b 100644 (file)
@@ -1,34 +1,51 @@
-/*-----------------------------------------------------------------------------+
-|           The ncurses menu library is  Copyright (C) 1995-1997               |
-|             by Juergen Pfeifer <Juergen.Pfeifer@T-Online.de>                 |
-|                          All Rights Reserved.                                |
-|                                                                              |
-| Permission to use, copy, modify, and distribute this software and its        |
-| documentation for any purpose and without fee is hereby granted, provided    |
-| that the above copyright notice appear in all copies and that both that      |
-| copyright notice and this permission notice appear in supporting             |
-| documentation, and that the name of the above listed copyright holder(s) not |
-| be used in advertising or publicity pertaining to distribution of the        |
-| software without specific, written prior permission.                         | 
-|                                                                              |
-| THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD TO  |
-| THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-  |
-| NESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR   |
-| ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RE- |
-| SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
-| NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH    |
-| THE USE OR PERFORMANCE OF THIS SOFTWARE.                                     |
-+-----------------------------------------------------------------------------*/
+/****************************************************************************
+ * Copyright 2020 Thomas E. Dickey                                          *
+ * Copyright 1998-2010,2012 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            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/****************************************************************************
+ *   Author:  Juergen Pfeifer, 1995,1997                                    *
+ ****************************************************************************/
 
 /***************************************************************************
-* Module menu_item_new                                                     *
+* Module m_item_new                                                        *
 * Create and destroy menu items                                            *
-* Set and get marker string for menu
+* Set and get marker string for menu                                       *
 ***************************************************************************/
 
 #include "menu.priv.h"
 
-MODULE_ID("$Id: m_item_new.c,v 1.5 1997/05/01 16:47:26 juergen Exp $")
+#if USE_WIDEC_SUPPORT
+#if HAVE_WCTYPE_H
+#include <wctype.h>
+#endif
+#endif
+
+MODULE_ID("$Id: m_item_new.c,v 1.36 2020/12/12 00:38:08 tom Exp $")
 
 /*---------------------------------------------------------------------------
 |   Facility      :  libnmenu  
@@ -40,16 +57,44 @@ MODULE_ID("$Id: m_item_new.c,v 1.5 1997/05/01 16:47:26 juergen Exp $")
 |   Return Values :  TRUE     - if string is printable
 |                    FALSE    - if string contains non-printable characters
 +--------------------------------------------------------------------------*/
-static bool Is_Printable_String(const char *s)
+static bool
+Is_Printable_String(const char *s)
 {
+  int result = TRUE;
+
+#if USE_WIDEC_SUPPORT
+  int count = (int)mbstowcs(0, s, 0);
+  wchar_t *temp = 0;
+
+  assert(s);
+
+  if (count > 0
+      && (temp = typeCalloc(wchar_t, (2 + (unsigned)count))) != 0)
+    {
+      int n;
+
+      mbstowcs(temp, s, (unsigned)count);
+      for (n = 0; n < count; ++n)
+       if (!iswprint((wint_t)temp[n]))
+         {
+           result = FALSE;
+           break;
+         }
+      free(temp);
+    }
+#else
   assert(s);
-  while(*s)
+  while (*s)
     {
-      if (!isprint((unsigned char)*s))
-       return FALSE;
+      if (!isprint(UChar(*s)))
+       {
+         result = FALSE;
+         break;
+       }
       s++;
     }
-  return TRUE;
+#endif
+  return result;
 }
 
 /*---------------------------------------------------------------------------
@@ -62,63 +107,47 @@ static bool Is_Printable_String(const char *s)
 |
 |   Return Values :  The item pointer or NULL if creation failed.
 +--------------------------------------------------------------------------*/
-ITEM *new_item(const char *name, const char *description)
+MENU_EXPORT(ITEM *)
+new_item(const char *name, const char *description)
 {
   ITEM *item;
-  
-  if ( !name || (*name == '\0') || !Is_Printable_String(name) )
+
+  T((T_CALLED("new_item(\"%s\", \"%s\")"),
+     name ? name : "",
+     description ? description : ""));
+
+  if (!name || (*name == '\0') || !Is_Printable_String(name))
     {
       item = (ITEM *)0;
-      SET_ERROR( E_BAD_ARGUMENT );
+      SET_ERROR(E_BAD_ARGUMENT);
     }
   else
     {
-      item = (ITEM *)calloc(1,sizeof(ITEM));
+      item = typeCalloc(ITEM, 1);
+
       if (item)
        {
-         *item  = _nc_Default_Item; /* hope we have struct assignment */
-         
-         item->name.length        = strlen(name);
-         item->name.str           = (char *)malloc(1 + item->name.length);
-         if (item->name.str)
-           {
-             strcpy(item->name.str, name);
-           }
-         else
-           {
-             free(item);
-             SET_ERROR( E_SYSTEM_ERROR );
-             return (ITEM *)0;
-           }
-         
-         if (description && (*description != '\0') && 
+         *item = _nc_Default_Item;     /* hope we have struct assignment */
+
+         item->name.length = (unsigned short)strlen(name);
+         item->name.str = name;
+
+         if (description && (*description != '\0') &&
              Is_Printable_String(description))
            {
-             item->description.length = strlen(description);         
-             item->description.str    = 
-               (char *)malloc(1 + item->description.length);
-             if (item->description.str)
-               {
-                 strcpy(item->description.str, description);
-               }
-             else
-               {
-                 free(item->name.str);
-                 free(item);
-                 SET_ERROR( E_SYSTEM_ERROR );
-                 return (ITEM *)0;
-               }
+             item->description.length = (unsigned short)strlen(description);
+             item->description.str = description;
            }
          else
            {
              item->description.length = 0;
-             item->description.str    = (char *)0;
+             item->description.str = (char *)0;
            }
        }
       else
-       SET_ERROR( E_SYSTEM_ERROR );
-    }  
-  return(item);
+       SET_ERROR(E_SYSTEM_ERROR);
+    }
+  returnItem(item);
 }
 
 /*---------------------------------------------------------------------------
@@ -132,21 +161,20 @@ ITEM *new_item(const char *name, const char *description)
 |                    E_BAD_ARGUMENT    - invalid value has been passed
 |                    E_CONNECTED       - item is still connected to a menu    
 +--------------------------------------------------------------------------*/
-int free_item(ITEM * item)
+MENU_EXPORT(int)
+free_item(ITEM *item)
 {
+  T((T_CALLED("free_item(%p)"), (void *)item));
+
   if (!item)
-    RETURN( E_BAD_ARGUMENT );
+    RETURN(E_BAD_ARGUMENT);
 
   if (item->imenu)
-    RETURN( E_CONNECTED );
-  
-  if (item->name.str)
-    free(item->name.str);
-  if (item->description.str)
-    free (item->description.str);
+    RETURN(E_CONNECTED);
+
   free(item);
 
-  RETURN( E_OK );
+  RETURN(E_OK);
 }
 
 /*---------------------------------------------------------------------------
@@ -166,16 +194,19 @@ int free_item(ITEM * item)
 |                    E_BAD_ARGUMENT     - an invalid value has been passed
 |                    E_SYSTEM_ERROR     - no memory to store mark
 +--------------------------------------------------------------------------*/
-int set_menu_mark(MENU * menu, const char * mark)
+MENU_EXPORT(int)
+set_menu_mark(MENU *menu, const char *mark)
 {
-  int l;
+  short l;
 
-  if ( mark && (*mark != '\0') && Is_Printable_String(mark) )
-    l = strlen(mark);
+  T((T_CALLED("set_menu_mark(%p,%s)"), (void *)menu, _nc_visbuf(mark)));
+
+  if (mark && (*mark != '\0') && Is_Printable_String(mark))
+    l = (short)strlen(mark);
   else
     l = 0;
 
-  if ( menu )
+  if (menu)
     {
       char *old_mark = menu->mark;
       unsigned short old_status = menu->status;
@@ -184,44 +215,45 @@ int set_menu_mark(MENU * menu, const char * mark)
        {
          /* If the menu is already posted, the geometry is fixed. Then
             we can only accept a mark with exactly the same length */
-         if (menu->marklen != l) 
+         if (menu->marklen != l)
            RETURN(E_BAD_ARGUMENT);
-       }       
+       }
       menu->marklen = l;
       if (l)
        {
-         menu->mark = (char *)malloc(l+1);
+         menu->mark = strdup(mark);
          if (menu->mark)
            {
-             strcpy(menu->mark, mark);
-             menu->status |= _MARK_ALLOCATED;
+             if (menu != &_nc_Default_Menu)
+               SetStatus(menu, _MARK_ALLOCATED);
            }
          else
            {
              menu->mark = old_mark;
+             menu->marklen = (short)((old_mark != 0) ? strlen(old_mark) : 0);
              RETURN(E_SYSTEM_ERROR);
            }
        }
       else
        menu->mark = (char *)0;
-      
+
       if ((old_status & _MARK_ALLOCATED) && old_mark)
        free(old_mark);
 
       if (menu->status & _POSTED)
        {
-         _nc_Draw_Menu( menu );
-         _nc_Show_Menu( menu );
+         _nc_Draw_Menu(menu);
+         _nc_Show_Menu(menu);
        }
       else
        {
          /* Recalculate the geometry */
-         _nc_Calculate_Item_Length_and_Width( menu );                  
+         _nc_Calculate_Item_Length_and_Width(menu);
        }
     }
   else
     {
-      return set_menu_mark(&_nc_Default_Menu, mark);
+      returnCode(set_menu_mark(&_nc_Default_Menu, mark));
     }
   RETURN(E_OK);
 }
@@ -234,9 +266,11 @@ int set_menu_mark(MENU * menu, const char * mark)
 |
 |   Return Values :  The marker string pointer or NULL if no marker defined
 +--------------------------------------------------------------------------*/
-const char *menu_mark(const MENU * menu)
+MENU_EXPORT(const char *)
+menu_mark(const MENU *menu)
 {
-  return Normalize_Menu( menu )->mark;
+  T((T_CALLED("menu_mark(%p)"), (const void *)menu));
+  returnPtr(Normalize_Menu(menu)->mark);
 }
 
 /* m_item_new.c */