Move DONT_REOPEN_PTY from src/s to configure
[bpt/emacs.git] / src / menu.c
index 7eda4c6..3b8ebb6 100644 (file)
@@ -1,6 +1,6 @@
 /* Platform-independent code for terminal communications.
 
-Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2011
+Copyright (C) 1986, 1988, 1993-1994, 1996, 1999-2012
   Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -67,6 +67,9 @@ Lisp_Object menu_items;
 
 /* If non-nil, means that the global vars defined here are already in use.
    Used to detect cases where we try to re-enter this non-reentrant code.  */
+#if ! (defined USE_GTK || defined USE_MOTIF)
+static
+#endif
 Lisp_Object menu_items_inuse;
 
 /* Number of slots currently allocated in menu_items.  */
@@ -126,7 +129,7 @@ discard_menu_items (void)
       menu_items = Qnil;
       menu_items_allocated = 0;
     }
-  xassert (NILP (menu_items_inuse));
+  eassert (NILP (menu_items_inuse));
 }
 
 #ifdef HAVE_NS
@@ -172,15 +175,17 @@ save_menu_items (void)
 }
 
 \f
-/* Make the menu_items vector twice as large.  */
+/* Ensure that there is room for ITEMS items in the menu_items vector.  */
 
 static void
-grow_menu_items (void)
+ensure_menu_items (int items)
 {
-  if ((INT_MAX - MENU_ITEMS_PANE_LENGTH) / 2 < menu_items_allocated)
-    memory_full (SIZE_MAX);
-  menu_items_allocated *= 2;
-  menu_items = larger_vector (menu_items, menu_items_allocated, Qnil);
+  int incr = items - (menu_items_allocated - menu_items_used);
+  if (0 < incr)
+    {
+      menu_items = larger_vector (menu_items, incr, INT_MAX);
+      menu_items_allocated = ASIZE (menu_items);
+    }
 }
 
 #if (defined USE_X_TOOLKIT || defined USE_GTK || defined HAVE_NS \
@@ -191,10 +196,9 @@ grow_menu_items (void)
 static void
 push_submenu_start (void)
 {
-  if (menu_items_used + 1 > menu_items_allocated)
-    grow_menu_items ();
-
-  XVECTOR (menu_items)->contents[menu_items_used++] = Qnil;
+  ensure_menu_items (1);
+  ASET (menu_items, menu_items_used, Qnil);
+  menu_items_used++;
   menu_items_submenu_depth++;
 }
 
@@ -203,10 +207,9 @@ push_submenu_start (void)
 static void
 push_submenu_end (void)
 {
-  if (menu_items_used + 1 > menu_items_allocated)
-    grow_menu_items ();
-
-  XVECTOR (menu_items)->contents[menu_items_used++] = Qlambda;
+  ensure_menu_items (1);
+  ASET (menu_items, menu_items_used, Qlambda);
+  menu_items_used++;
   menu_items_submenu_depth--;
 }
 
@@ -217,10 +220,9 @@ push_submenu_end (void)
 static void
 push_left_right_boundary (void)
 {
-  if (menu_items_used + 1 > menu_items_allocated)
-    grow_menu_items ();
-
-  XVECTOR (menu_items)->contents[menu_items_used++] = Qquote;
+  ensure_menu_items (1);
+  ASET (menu_items, menu_items_used, Qquote);
+  menu_items_used++;
 }
 
 /* Start a new menu pane in menu_items.
@@ -229,14 +231,15 @@ push_left_right_boundary (void)
 static void
 push_menu_pane (Lisp_Object name, Lisp_Object prefix_vec)
 {
-  if (menu_items_used + MENU_ITEMS_PANE_LENGTH > menu_items_allocated)
-    grow_menu_items ();
-
+  ensure_menu_items (MENU_ITEMS_PANE_LENGTH);
   if (menu_items_submenu_depth == 0)
     menu_items_n_panes++;
-  XVECTOR (menu_items)->contents[menu_items_used++] = Qt;
-  XVECTOR (menu_items)->contents[menu_items_used++] = name;
-  XVECTOR (menu_items)->contents[menu_items_used++] = prefix_vec;
+  ASET (menu_items, menu_items_used, Qt);
+  menu_items_used++;
+  ASET (menu_items, menu_items_used, name);
+  menu_items_used++;
+  ASET (menu_items, menu_items_used, prefix_vec);
+  menu_items_used++;
 }
 
 /* Push one menu item into the current pane.  NAME is the string to
@@ -250,8 +253,7 @@ push_menu_pane (Lisp_Object name, Lisp_Object prefix_vec)
 static void
 push_menu_item (Lisp_Object name, Lisp_Object enable, Lisp_Object key, Lisp_Object def, Lisp_Object equiv, Lisp_Object type, Lisp_Object selected, Lisp_Object help)
 {
-  if (menu_items_used + MENU_ITEMS_ITEM_LENGTH > menu_items_allocated)
-    grow_menu_items ();
+  ensure_menu_items (MENU_ITEMS_ITEM_LENGTH);
 
   ASET (menu_items, menu_items_used + MENU_ITEMS_ITEM_NAME,    name);
   ASET (menu_items, menu_items_used + MENU_ITEMS_ITEM_ENABLE,  enable);
@@ -347,10 +349,10 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
   if (!res)
     return;                    /* Not a menu item.  */
 
-  map = XVECTOR (item_properties)->contents[ITEM_PROPERTY_MAP];
+  map = AREF (item_properties, ITEM_PROPERTY_MAP);
 
-  enabled = XVECTOR (item_properties)->contents[ITEM_PROPERTY_ENABLE];
-  item_string = XVECTOR (item_properties)->contents[ITEM_PROPERTY_NAME];
+  enabled = AREF (item_properties, ITEM_PROPERTY_ENABLE);
+  item_string = AREF (item_properties, ITEM_PROPERTY_NAME);
 
   if (!NILP (map) && SREF (item_string, 0) == '@')
     {
@@ -361,17 +363,17 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
       return;
     }
 
-#if defined(HAVE_X_WINDOWS) || defined(MSDOS)
+#if defined (HAVE_X_WINDOWS) || defined (MSDOS)
 #ifndef HAVE_BOXES
   /* Simulate radio buttons and toggle boxes by putting a prefix in
      front of them.  */
   {
     Lisp_Object prefix = Qnil;
-    Lisp_Object type = XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE];
+    Lisp_Object type = AREF (item_properties, ITEM_PROPERTY_TYPE);
     if (!NILP (type))
       {
        Lisp_Object selected
-         = XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED];
+         = AREF (item_properties, ITEM_PROPERTY_SELECTED);
 
        if (skp->notbuttons)
          /* The first button. Line up previous items in this menu.  */
@@ -382,7 +384,7 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
            while (idx < menu_items_used)
              {
                tem
-                 = XVECTOR (menu_items)->contents[idx + MENU_ITEMS_ITEM_NAME];
+                 = AREF (menu_items, idx + MENU_ITEMS_ITEM_NAME);
                if (NILP (tem))
                  {
                    idx++;
@@ -401,8 +403,8 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
                  {
                    if (!submenu && SREF (tem, 0) != '\0'
                        && SREF (tem, 0) != '-')
-                     XVECTOR (menu_items)->contents[idx + MENU_ITEMS_ITEM_NAME]
-                       = concat2 (build_string ("    "), tem);
+                     ASET (menu_items, idx + MENU_ITEMS_ITEM_NAME,
+                           concat2 (build_string ("    "), tem));
                    idx += MENU_ITEMS_ITEM_LENGTH;
                  }
              }
@@ -434,11 +436,11 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
 #endif /* HAVE_X_WINDOWS || MSDOS */
 
   push_menu_item (item_string, enabled, key,
-                 XVECTOR (item_properties)->contents[ITEM_PROPERTY_DEF],
-                 XVECTOR (item_properties)->contents[ITEM_PROPERTY_KEYEQ],
-                 XVECTOR (item_properties)->contents[ITEM_PROPERTY_TYPE],
-                 XVECTOR (item_properties)->contents[ITEM_PROPERTY_SELECTED],
-                 XVECTOR (item_properties)->contents[ITEM_PROPERTY_HELP]);
+                 AREF (item_properties, ITEM_PROPERTY_DEF),
+                 AREF (item_properties, ITEM_PROPERTY_KEYEQ),
+                 AREF (item_properties, ITEM_PROPERTY_TYPE),
+                 AREF (item_properties, ITEM_PROPERTY_SELECTED),
+                 AREF (item_properties, ITEM_PROPERTY_HELP));
 
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI)
   /* Display a submenu using the toolkit.  */
@@ -455,9 +457,9 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
    and generate menu panes for them in menu_items.  */
 
 static void
-keymap_panes (Lisp_Object *keymaps, int nmaps)
+keymap_panes (Lisp_Object *keymaps, ptrdiff_t nmaps)
 {
-  int mapno;
+  ptrdiff_t mapno;
 
   init_menu_items ();
 
@@ -529,16 +531,17 @@ int
 parse_single_submenu (Lisp_Object item_key, Lisp_Object item_name, Lisp_Object maps)
 {
   Lisp_Object length;
-  int len;
+  EMACS_INT len;
   Lisp_Object *mapvec;
-  int i;
+  ptrdiff_t i;
   int top_level_items = 0;
+  USE_SAFE_ALLOCA;
 
   length = Flength (maps);
   len = XINT (length);
 
   /* Convert the list MAPS into a vector MAPVEC.  */
-  mapvec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
+  SAFE_ALLOCA_LISP (mapvec, len);
   for (i = 0; i < len; i++)
     {
       mapvec[i] = Fcar (maps);
@@ -568,6 +571,7 @@ parse_single_submenu (Lisp_Object item_key, Lisp_Object item_name, Lisp_Object m
        }
     }
 
+  SAFE_FREE ();
   return top_level_items;
 }
 
@@ -628,8 +632,7 @@ digest_single_submenu (int start, int end, int top_level_items)
   widget_value **submenu_stack;
   int panes_seen = 0;
 
-  submenu_stack
-    = (widget_value **) alloca (menu_items_used * sizeof (widget_value *));
+  submenu_stack = alloca (menu_items_used * sizeof *submenu_stack);
   wv = xmalloc_widget_value ();
   wv->name = "menu";
   wv->value = 0;
@@ -647,27 +650,27 @@ digest_single_submenu (int start, int end, int top_level_items)
   i = start;
   while (i < end)
     {
-      if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
+      if (EQ (AREF (menu_items, i), Qnil))
        {
          submenu_stack[submenu_depth++] = save_wv;
          save_wv = prev_wv;
          prev_wv = 0;
          i++;
        }
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
+      else if (EQ (AREF (menu_items, i), Qlambda))
        {
          prev_wv = save_wv;
          save_wv = submenu_stack[--submenu_depth];
          i++;
        }
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qt)
+      else if (EQ (AREF (menu_items, i), Qt)
               && submenu_depth != 0)
        i += MENU_ITEMS_PANE_LENGTH;
       /* Ignore a nil in the item list.
         It's meaningful only for dialog boxes.  */
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+      else if (EQ (AREF (menu_items, i), Qquote))
        i += 1;
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+      else if (EQ (AREF (menu_items, i), Qt))
        {
          /* Create a new pane.  */
          Lisp_Object pane_name;
@@ -675,7 +678,7 @@ digest_single_submenu (int start, int end, int top_level_items)
 
          panes_seen++;
 
-         pane_name = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_NAME];
+         pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
 
 #ifdef HAVE_NTGUI
          if (STRINGP (pane_name))
@@ -889,31 +892,31 @@ find_and_call_menu_selection (FRAME_PTR f, int menu_bar_items_used, Lisp_Object
   int i;
 
   entry = Qnil;
-  subprefix_stack = (Lisp_Object *) alloca (menu_bar_items_used * sizeof (Lisp_Object));
+  subprefix_stack = alloca (menu_bar_items_used * sizeof *subprefix_stack);
   prefix = Qnil;
   i = 0;
 
   while (i < menu_bar_items_used)
     {
-      if (EQ (XVECTOR (vector)->contents[i], Qnil))
+      if (EQ (AREF (vector, i), Qnil))
        {
          subprefix_stack[submenu_depth++] = prefix;
          prefix = entry;
          i++;
        }
-      else if (EQ (XVECTOR (vector)->contents[i], Qlambda))
+      else if (EQ (AREF (vector, i), Qlambda))
        {
          prefix = subprefix_stack[--submenu_depth];
          i++;
        }
-      else if (EQ (XVECTOR (vector)->contents[i], Qt))
+      else if (EQ (AREF (vector, i), Qt))
        {
-         prefix = XVECTOR (vector)->contents[i + MENU_ITEMS_PANE_PREFIX];
+         prefix = AREF (vector, i + MENU_ITEMS_PANE_PREFIX);
          i += MENU_ITEMS_PANE_LENGTH;
        }
       else
        {
-         entry = XVECTOR (vector)->contents[i + MENU_ITEMS_ITEM_VALUE];
+         entry = AREF (vector, i + MENU_ITEMS_ITEM_VALUE);
          /* Treat the pointer as an integer.  There's no problem
             as long as pointers have enough bits to hold small integers.  */
          if ((intptr_t) client_data == i)
@@ -974,36 +977,36 @@ find_and_return_menu_selection (FRAME_PTR f, int keymaps, void *client_data)
   prefix = entry = Qnil;
   i = 0;
   subprefix_stack =
-    (Lisp_Object *)alloca(menu_items_used * sizeof (Lisp_Object));
+    (Lisp_Object *)alloca (menu_items_used * sizeof (Lisp_Object));
 
   while (i < menu_items_used)
     {
-      if (EQ (XVECTOR (menu_items)->contents[i], Qnil))
+      if (EQ (AREF (menu_items, i), Qnil))
         {
           subprefix_stack[submenu_depth++] = prefix;
           prefix = entry;
           i++;
         }
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qlambda))
+      else if (EQ (AREF (menu_items, i), Qlambda))
         {
           prefix = subprefix_stack[--submenu_depth];
           i++;
         }
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qt))
+      else if (EQ (AREF (menu_items, i), Qt))
         {
           prefix
-            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_PANE_PREFIX];
+            = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
           i += MENU_ITEMS_PANE_LENGTH;
         }
       /* Ignore a nil in the item list.
          It's meaningful only for dialog boxes.  */
-      else if (EQ (XVECTOR (menu_items)->contents[i], Qquote))
+      else if (EQ (AREF (menu_items, i), Qquote))
         i += 1;
       else
         {
           entry
-            = XVECTOR (menu_items)->contents[i + MENU_ITEMS_ITEM_VALUE];
-          if ((EMACS_INT)client_data ==  (EMACS_INT)(&XVECTOR (menu_items)->contents[i]))
+            = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
+          if (&AREF (menu_items, i) == client_data)
             {
               if (keymaps != 0)
                 {
@@ -1079,7 +1082,7 @@ no quit occurs and `x-popup-menu' returns nil.  */)
   Lisp_Object x, y, window;
   int keymaps = 0;
   int for_click = 0;
-  int specpdl_count = SPECPDL_INDEX ();
+  ptrdiff_t specpdl_count = SPECPDL_INDEX ();
   struct gcpro gcpro1;
 
   if (NILP (position))
@@ -1172,9 +1175,6 @@ no quit occurs and `x-popup-menu' returns nil.  */)
          }
       }
 
-    CHECK_NUMBER (x);
-    CHECK_NUMBER (y);
-
     /* Decode where to put the menu.  */
 
     if (FRAMEP (window))
@@ -1197,6 +1197,16 @@ no quit occurs and `x-popup-menu' returns nil.  */)
         but I don't want to make one now.  */
       CHECK_WINDOW (window);
 
+    CHECK_RANGED_INTEGER (x,
+                         (xpos < INT_MIN - MOST_NEGATIVE_FIXNUM
+                          ? (EMACS_INT) INT_MIN - xpos
+                          : MOST_NEGATIVE_FIXNUM),
+                         INT_MAX - xpos);
+    CHECK_RANGED_INTEGER (y,
+                         (ypos < INT_MIN - MOST_NEGATIVE_FIXNUM
+                          ? (EMACS_INT) INT_MIN - ypos
+                          : MOST_NEGATIVE_FIXNUM),
+                         INT_MAX - ypos);
     xpos += XINT (x);
     ypos += XINT (y);
 
@@ -1245,11 +1255,12 @@ no quit occurs and `x-popup-menu' returns nil.  */)
   else if (CONSP (menu) && KEYMAPP (XCAR (menu)))
     {
       /* We were given a list of keymaps.  */
-      int nmaps = XFASTINT (Flength (menu));
-      Lisp_Object *maps
-       = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object));
-      int i;
+      EMACS_INT nmaps = XFASTINT (Flength (menu));
+      Lisp_Object *maps;
+      ptrdiff_t i;
+      USE_SAFE_ALLOCA;
 
+      SAFE_ALLOCA_LISP (maps, nmaps);
       title = Qnil;
 
       /* The first keymap that has a prompt string
@@ -1273,6 +1284,8 @@ no quit occurs and `x-popup-menu' returns nil.  */)
        ASET (menu_items, MENU_ITEMS_PANE_NAME, title);
 
       keymaps = 1;
+
+      SAFE_FREE ();
     }
   else
     {