emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Problem report #60


From: Dan Nicolaescu
Subject: Problem report #60
Date: Tue, 11 Apr 2006 08:48:33 -0700

CID: 60
Checker: UNINIT (help)
File: emacs/src/keyboard.c
Function: read_key_sequence
Description: Using uninitialized value "original_uppercase"

Event var_decl: Declared variable "original_uppercase" without initializer
Also see events: [uninit_use]

8608      volatile Lisp_Object original_uppercase;
8609      volatile int original_uppercase_position = -1;
8610    
8611      /* Gets around Microsoft compiler limitations.  */
8612      int dummyflag = 0;
8613    
8614      struct buffer *starting_buffer;
8615    
8616      /* List of events for which a fake prefix key has been generated.  */
8617      volatile Lisp_Object fake_prefixed_keys = Qnil;
8618    
8619    #if defined (GOBBLE_FIRST_EVENT)
8620      int junk;
8621    #endif
8622    
8623      struct gcpro gcpro1;
8624    
8625      GCPRO1 (fake_prefixed_keys);
8626      raw_keybuf_count = 0;
8627    
8628      last_nonmenu_event = Qnil;
8629    
8630      delayed_switch_frame = Qnil;
8631      fkey.map = fkey.parent = Vfunction_key_map;
8632      keytran.map = keytran.parent = Vkey_translation_map;
8633      /* If there is no translation-map, turn off scanning.  */
8634      fkey.start = fkey.end = KEYMAPP (fkey.map) ? 0 : bufsize + 1;
8635      keytran.start = keytran.end = KEYMAPP (keytran.map) ? 0 : bufsize + 1;
8636    
8637      if (INTERACTIVE)
8638        {
8639          if (!NILP (prompt))
8640            echo_prompt (prompt);
8641          else if (cursor_in_echo_area
8642                   && (FLOATP (Vecho_keystrokes) || INTEGERP 
(Vecho_keystrokes))
8643                   && NILP (Fzerop (Vecho_keystrokes)))
8644            /* This doesn't put in a dash if the echo buffer is empty, so
8645               you don't always see a dash hanging out in the minibuffer.  
*/
8646            echo_dash ();
8647        }
8648    
8649      /* Record the initial state of the echo area and this_command_keys;
8650         we will need to restore them if we replay a key sequence.  */
8651      if (INTERACTIVE)
8652        echo_start = echo_length ();
8653      keys_start = this_command_key_count;
8654      this_single_command_key_start = keys_start;
8655    
8656    #if defined (GOBBLE_FIRST_EVENT)
8657      /* This doesn't quite work, because some of the things that read_char
8658         does cannot safely be bypassed.  It seems too risky to try to make
8659         this work right.  */
8660    
8661      /* Read the first char of the sequence specially, before setting
8662         up any keymaps, in case a filter runs and switches buffers on us.  
*/
8663      first_event = read_char (NILP (prompt), 0, submaps, 
last_nonmenu_event,
8664                               &junk);
8665    #endif /* GOBBLE_FIRST_EVENT */
8666    
8667      orig_local_map = get_local_map (PT, current_buffer, Qlocal_map);
8668      orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
8669      from_string = Qnil;
8670    
8671      /* We jump here when the key sequence has been thoroughly changed, and
8672         we need to rescan it starting from the beginning.  When we jump 
here,
8673         keybuf[0..mock_input] holds the sequence we should reread.  */
8674     replay_sequence:
8675    
8676      starting_buffer = current_buffer;
8677      first_unbound = bufsize + 1;
8678    
8679      /* Build our list of keymaps.
8680         If we recognize a function key and replace its escape sequence in
8681         keybuf with its symbol, or if the sequence starts with a mouse
8682         click and we need to switch buffers, we jump back here to rebuild
8683         the initial keymaps from the current buffer.  */
8684      nmaps = 0;
8685    
8686      if (!NILP (current_kboard->Voverriding_terminal_local_map)
8687          || !NILP (Voverriding_local_map))
8688        {
8689          if (3 > nmaps_allocated)
8690            {
8691              submaps = (Lisp_Object *) alloca (3 * sizeof (submaps[0]));
8692              defs    = (Lisp_Object *) alloca (3 * sizeof (defs[0]));
8693              nmaps_allocated = 3;
8694            }
8695          if (!NILP (current_kboard->Voverriding_terminal_local_map))
8696            submaps[nmaps++] = 
current_kboard->Voverriding_terminal_local_map;
8697          if (!NILP (Voverriding_local_map))
8698            submaps[nmaps++] = Voverriding_local_map;
8699        }
8700      else
8701        {
8702          int nminor;
8703          int total;
8704          Lisp_Object *maps;
8705    
8706          nminor = current_minor_maps (0, &maps);
8707          total = nminor + (!NILP (orig_keymap) ? 3 : 2);
8708    
8709          if (total > nmaps_allocated)
8710            {
8711              submaps = (Lisp_Object *) alloca (total * sizeof 
(submaps[0]));
8712              defs    = (Lisp_Object *) alloca (total * sizeof (defs[0]));
8713              nmaps_allocated = total;
8714            }
8715    
8716          if (!NILP (orig_keymap))
8717            submaps[nmaps++] = orig_keymap;
8718    
8719          bcopy (maps, (void *) (submaps + nmaps),
8720                 nminor * sizeof (submaps[0]));
8721    
8722          nmaps += nminor;
8723    
8724          submaps[nmaps++] = orig_local_map;
8725        }
8726      submaps[nmaps++] = current_global_map;
8727    
8728      /* Find an accurate initial value for first_binding.  */
8729      for (first_binding = 0; first_binding < nmaps; first_binding++)
8730        if (! NILP (submaps[first_binding]))
8731          break;
8732    
8733      /* Start from the beginning in keybuf.  */
8734      t = 0;
8735    
8736      /* These are no-ops the first time through, but if we restart, they
8737         revert the echo area and this_command_keys to their original 
state.  */
8738      this_command_key_count = keys_start;
8739      if (INTERACTIVE && t < mock_input)
8740        echo_truncate (echo_start);
8741    
8742      /* If the best binding for the current key sequence is a keymap, or
8743         we may be looking at a function key's escape sequence, keep on
8744         reading.  */

At conditional (1): "((first_binding < nmaps) ? ((*(submaps + (first_binding * 
4)) != Qnil) ? 1 : (0)) : ((fkey).start < t || (keytran).start < t)) != 0" 
taking true path

8745      while (first_binding < nmaps
8746             /* Keep reading as long as there's a prefix binding.  */
8747             ? !NILP (submaps[first_binding])
8748             /* Don't return in the middle of a possible function key 
sequence,
8749                if the only bindings we found were via case conversion.
8750                Thus, if ESC O a has a function-key-map translation
8751                and ESC o has a binding, don't return after ESC O,
8752                so that we can translate ESC O plus the next character.  */
8753             : (fkey.start < t || keytran.start < t))
8754        {
8755          Lisp_Object key;
8756          int used_mouse_menu = 0;
8757    
8758          /* Where the last real key started.  If we need to throw away a
8759             key that has expanded into more than one element of keybuf
8760             (say, a mouse click on the mode line which is being treated
8761             as [mode-line (mouse-...)], then we backtrack to this point
8762             of keybuf.  */
8763          volatile int last_real_key_start;
8764    
8765          /* These variables are analogous to echo_start and keys_start;
8766             while those allow us to restart the entire key sequence,
8767             echo_local_start and keys_local_start allow us to throw away
8768             just one key.  */
8769          volatile int echo_local_start, keys_local_start, 
local_first_binding;
8770    
8771          eassert (fkey.end == t || (fkey.end > t && fkey.end <= 
mock_input));
8772          eassert (fkey.start <= fkey.end);
8773          eassert (keytran.start <= keytran.end);
8774          /* key-translation-map is applied *after* function-key-map.  */
8775          eassert (keytran.end <= fkey.start);
8776    

At conditional (2): "first_unbound < (fkey).start" taking true path
At conditional (3): "first_unbound < (keytran).start" taking false path

8777          if (first_unbound < fkey.start && first_unbound < keytran.start)
8778            { /* The prefix upto first_unbound has no binding and has
8779                 no translation left to do either, so we know it's unbound.
8780                 If we don't stop now, we risk staying here indefinitely
8781                 (if the user keeps entering fkey or keytran prefixes
8782                 like C-c ESC ESC ESC ESC ...)  */
8783              int i;
8784              for (i = first_unbound + 1; i < t; i++)
8785                keybuf[i - first_unbound - 1] = keybuf[i];
8786              mock_input = t - first_unbound - 1;
8787              fkey.end = fkey.start -= first_unbound + 1;
8788              fkey.map = fkey.parent;
8789              keytran.end = keytran.start -= first_unbound + 1;
8790              keytran.map = keytran.parent;
8791              goto replay_sequence;
8792            }
8793    

At conditional (4): "t >= bufsize" taking false path

8794          if (t >= bufsize)
8795            error ("Key sequence too long");
8796    

At conditional (5): "Vexecuting_kbd_macro == Qnil" taking true path
At conditional (6): "noninteractive == 0" taking true path

8797          if (INTERACTIVE)
8798            echo_local_start = echo_length ();
8799          keys_local_start = this_command_key_count;
8800          local_first_binding = first_binding;
8801    
8802        replay_key:
8803          /* These are no-ops, unless we throw away a keystroke below and
8804             jumped back up to replay_key; in that case, these restore the
8805             variables to their original state, allowing us to replay the
8806             loop.  */

At conditional (7): "Vexecuting_kbd_macro == Qnil" taking true path
At conditional (8): "noninteractive == 0" taking true path
At conditional (9): "t < mock_input" taking false path

8807          if (INTERACTIVE && t < mock_input)
8808            echo_truncate (echo_local_start);
8809          this_command_key_count = keys_local_start;
8810          first_binding = local_first_binding;
8811    
8812          /* By default, assume each event is "real".  */
8813          last_real_key_start = t;
8814    
8815          /* Does mock_input indicate that we are re-reading a key 
sequence?  */

At conditional (10): "t < mock_input" taking false path

8816          if (t < mock_input)
8817            {
8818              key = keybuf[t];
8819              add_command_key (key);
8820              if ((FLOATP (Vecho_keystrokes) || INTEGERP (Vecho_keystrokes))
8821                  && NILP (Fzerop (Vecho_keystrokes)))
8822                echo_char (key);
8823            }
8824    
8825          /* If not, we should actually read a character.  */
8826          else
8827            {
8828              {
8829    #ifdef MULTI_KBOARD
8830                KBOARD *interrupted_kboard = current_kboard;

At conditional (11): "selected_frame & 7 == 4" taking true path
At conditional (12): "((0), (selected_frame & -8))->size & 1073742848 == 
1073742848" taking true path
At conditional (13): "(((0), (selected_frame & -8))->output_data).nothing != 0" 
taking true path

8831                struct frame *interrupted_frame = SELECTED_FRAME ();

At conditional (14): "_setjmp != 0" taking false path

8832                if (setjmp (wrong_kboard_jmpbuf))
8833                  {
8834                    if (!NILP (delayed_switch_frame))
8835                      {
8836                        interrupted_kboard->kbd_queue
8837                          = Fcons (delayed_switch_frame,
8838                                   interrupted_kboard->kbd_queue);
8839                        delayed_switch_frame = Qnil;
8840                      }
8841                    while (t > 0)
8842                      interrupted_kboard->kbd_queue
8843                        = Fcons (keybuf[--t], 
interrupted_kboard->kbd_queue);
8844    
8845                    /* If the side queue is non-empty, ensure it begins 
with a
8846                       switch-frame, so we'll replay it in the right 
context.  */
8847                    if (CONSP (interrupted_kboard->kbd_queue)
8848                        && (key = XCAR (interrupted_kboard->kbd_queue),
8849                            !(EVENT_HAS_PARAMETERS (key)
8850                              && EQ (EVENT_HEAD_KIND (EVENT_HEAD (key)),
8851                                     Qswitch_frame))))
8852                      {
8853                        Lisp_Object frame;
8854                        XSETFRAME (frame, interrupted_frame);
8855                        interrupted_kboard->kbd_queue
8856                          = Fcons (make_lispy_switch_frame (frame),
8857                                   interrupted_kboard->kbd_queue);
8858                      }
8859                    mock_input = 0;
8860                    orig_local_map = get_local_map (PT, current_buffer, 
Qlocal_map);
8861                    orig_keymap = get_local_map (PT, current_buffer, 
Qkeymap);
8862                    goto replay_sequence;
8863                  }
8864    #endif

At conditional (15): "prompt == Qnil" taking false path

8865                key = read_char (NILP (prompt), nmaps,
8866                                 (Lisp_Object *) submaps, 
last_nonmenu_event,
8867                                 &used_mouse_menu);
8868              }
8869    
8870              /* read_char returns t when it shows a menu and the user 
rejects it.
8871                 Just return -1.  */

At conditional (16): "key == Qt" taking false path

8872              if (EQ (key, Qt))
8873                {
8874                  unbind_to (count, Qnil);
8875                  UNGCPRO;
8876                  return -1;
8877                }
8878    
8879              /* read_char returns -1 at the end of a macro.
8880                 Emacs 18 handles this by returning immediately with a
8881                 zero, so that's what we'll do.  */

At conditional (17): "key & 7 == 0" taking true path
At conditional (18): "key >> 3 == -1" taking true path

8882              if (INTEGERP (key) && XINT (key) == -1)
8883                {
8884                  t = 0;
8885                  /* The Microsoft C compiler can't handle the goto that
8886                     would go here.  */
8887                  dummyflag = 1;
8888                  break;
8889                }
8890    
8891              /* If the current buffer has been changed from under us, the
8892                 keymap may have changed, so replay the sequence.  */
8893              if (BUFFERP (key))
8894                {
8895                  timer_resume_idle ();
8896    
8897                  mock_input = t;
8898                  /* Reset the current buffer from the selected window
8899                     in case something changed the former and not the 
latter.
8900                     This is to be more consistent with the behavior
8901                     of the command_loop_1.  */
8902                  if (fix_current_buffer)
8903                    {
8904                      if (! FRAME_LIVE_P (XFRAME (selected_frame)))
8905                        Fkill_emacs (Qnil);
8906                      if (XBUFFER (XWINDOW (selected_window)->buffer) != 
current_buffer)
8907                        Fset_buffer (XWINDOW (selected_window)->buffer);
8908                    }
8909    
8910                  orig_local_map = get_local_map (PT, current_buffer, 
Qlocal_map);
8911                  orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
8912                  goto replay_sequence;
8913                }
8914    
8915              /* If we have a quit that was typed in another frame, and
8916                 quit_throw_to_read_char switched buffers,
8917                 replay to get the right keymap.  */
8918              if (INTEGERP (key)
8919                  && XINT (key) == quit_char
8920                  && current_buffer != starting_buffer)
8921                {
8922                  GROW_RAW_KEYBUF;
8923                  XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
8924                  keybuf[t++] = key;
8925                  mock_input = t;
8926                  Vquit_flag = Qnil;
8927                  orig_local_map = get_local_map (PT, current_buffer, 
Qlocal_map);
8928                  orig_keymap = get_local_map (PT, current_buffer, Qkeymap);
8929                  goto replay_sequence;
8930                }
8931    
8932              Vquit_flag = Qnil;
8933    
8934              if (EVENT_HAS_PARAMETERS (key)
8935                  /* Either a `switch-frame' or a `select-window' event.  */
8936                  && EQ (EVENT_HEAD_KIND (EVENT_HEAD (key)), Qswitch_frame))
8937                {
8938                  /* If we're at the beginning of a key sequence, and the 
caller
8939                     says it's okay, go ahead and return this event.  If 
we're
8940                     in the midst of a key sequence, delay it until the 
end. */
8941                  if (t > 0 || !can_return_switch_frame)
8942                    {
8943                      delayed_switch_frame = key;
8944                      goto replay_key;
8945                    }
8946                }
8947    
8948              GROW_RAW_KEYBUF;
8949              XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = key;
8950            }
8951    
8952          /* Clicks in non-text areas get prefixed by the symbol
8953             in their CHAR-ADDRESS field.  For example, a click on
8954             the mode line is prefixed by the symbol `mode-line'.
8955    
8956             Furthermore, key sequences beginning with mouse clicks
8957             are read using the keymaps of the buffer clicked on, not
8958             the current buffer.  So we may have to switch the buffer
8959             here.
8960    
8961             When we turn one event into two events, we must make sure
8962             that neither of the two looks like the original--so that,
8963             if we replay the events, they won't be expanded again.
8964             If not for this, such reexpansion could happen either here
8965             or when user programs play with this-command-keys.  */
8966          if (EVENT_HAS_PARAMETERS (key))
8967            {
8968              Lisp_Object kind;
8969              Lisp_Object string;
8970    
8971              kind = EVENT_HEAD_KIND (EVENT_HEAD (key));
8972              if (EQ (kind, Qmouse_click))
8973                {
8974                  Lisp_Object window, posn;
8975    
8976                  window = POSN_WINDOW      (EVENT_START (key));
8977                  posn   = POSN_POSN (EVENT_START (key));
8978    
8979                  if (CONSP (posn)
8980                      || (!NILP (fake_prefixed_keys)
8981                          && !NILP (Fmemq (key, fake_prefixed_keys))))
8982                    {
8983                      /* We're looking a second time at an event for which
8984                         we generated a fake prefix key.  Set
8985                         last_real_key_start appropriately.  */
8986                      if (t > 0)
8987                        last_real_key_start = t - 1;
8988                    }
8989    
8990                  /* Key sequences beginning with mouse clicks are
8991                     read using the keymaps in the buffer clicked on,
8992                     not the current buffer.  If we're at the
8993                     beginning of a key sequence, switch buffers.  */
8994                  if (last_real_key_start == 0
8995                      && WINDOWP (window)
8996                      && BUFFERP (XWINDOW (window)->buffer)
8997                      && XBUFFER (XWINDOW (window)->buffer) != 
current_buffer)
8998                    {
8999                      XVECTOR (raw_keybuf)->contents[raw_keybuf_count++] = 
key;
9000                      keybuf[t] = key;
9001                      mock_input = t + 1;
9002    
9003                      /* Arrange to go back to the original buffer once 
we're
9004                         done reading the key sequence.  Note that we can't
9005                         use save_excursion_{save,restore} here, because 
they
9006                         save point as well as the current buffer; we don't
9007                         want to save point, because redisplay may change 
it,
9008                         to accommodate a Fset_window_start or something.  
We
9009                         don't want to do this at the top of the function,
9010                         because we may get input from a subprocess which
9011                         wants to change the selected window and stuff (say,
9012                         emacsclient).  */
9013                      record_unwind_protect (Fset_buffer, Fcurrent_buffer 
());
9014    
9015                      if (! FRAME_LIVE_P (XFRAME (selected_frame)))
9016                        Fkill_emacs (Qnil);
9017                      set_buffer_internal (XBUFFER (XWINDOW 
(window)->buffer));
9018                      orig_local_map = get_local_map (PT, current_buffer,
9019                                                      Qlocal_map);
9020                      orig_keymap = get_local_map (PT, current_buffer, 
Qkeymap);
9021                      goto replay_sequence;
9022                    }
9023    
9024                  /* For a mouse click, get the local text-property keymap
9025                     of the place clicked on, rather than point.  */
9026                  if (last_real_key_start == 0
9027                      && CONSP (XCDR (key))
9028                      && ! localized_local_map)
9029                    {
9030                      Lisp_Object map_here, start, pos;
9031    
9032                      localized_local_map = 1;
9033                      start = EVENT_START (key);
9034    
9035                      if (CONSP (start) && POSN_INBUFFER_P (start))
9036                        {
9037                          pos = POSN_BUFFER_POSN (start);
9038                          if (INTEGERP (pos)
9039                              && XINT (pos) >= BEG && XINT (pos) <= Z)
9040                            {
9041                              map_here = get_local_map (XINT (pos),
9042                                                        current_buffer, 
Qlocal_map);
9043                              if (!EQ (map_here, orig_local_map))
9044                                {
9045                                  orig_local_map = map_here;
9046                                  keybuf[t] = key;
9047                                  mock_input = t + 1;
9048    
9049                                  goto replay_sequence;
9050                                }
9051                              map_here = get_local_map (XINT (pos),
9052                                                         current_buffer, 
Qkeymap);
9053                              if (!EQ (map_here, orig_keymap))
9054                                {
9055                                  orig_keymap = map_here;
9056                                  keybuf[t] = key;
9057                                  mock_input = t + 1;
9058    
9059                                  goto replay_sequence;
9060                                }
9061                            }
9062                        }
9063                    }
9064    
9065                  /* Expand mode-line and scroll-bar events into two events:
9066                     use posn as a fake prefix key.  */
9067                  if (SYMBOLP (posn)
9068                      && (NILP (fake_prefixed_keys)
9069                          || NILP (Fmemq (key, fake_prefixed_keys))))
9070                    {
9071                      if (t + 1 >= bufsize)
9072                        error ("Key sequence too long");
9073    
9074                      keybuf[t]     = posn;
9075                      keybuf[t + 1] = key;
9076                      mock_input    = t + 2;
9077    
9078                      /* Record that a fake prefix key has been generated
9079                         for KEY.  Don't modify the event; this would
9080                         prevent proper action when the event is pushed
9081                         back into unread-command-events.  */
9082                      fake_prefixed_keys = Fcons (key, fake_prefixed_keys);
9083    
9084                      /* If on a mode line string with a local keymap,
9085                         reconsider the key sequence with that keymap.  */
9086                      if (string = POSN_STRING (EVENT_START (key)),
9087                          (CONSP (string) && STRINGP (XCAR (string))))
9088                        {
9089                          Lisp_Object pos, map, map2;
9090    
9091                          pos = XCDR (string);
9092                          string = XCAR (string);
9093                          if (XINT (pos) >= 0
9094                              && XINT (pos) < SCHARS (string))
9095                            {
9096                              map = Fget_text_property (pos, Qlocal_map, 
string);
9097                              if (!NILP (map))
9098                                orig_local_map = map;
9099                              map2 = Fget_text_property (pos, Qkeymap, 
string);
9100                              if (!NILP (map2))
9101                                orig_keymap = map2;
9102                              if (!NILP (map) || !NILP (map2))
9103                                goto replay_sequence;
9104                            }
9105                        }
9106    
9107                      goto replay_key;
9108                    }
9109                  else if (NILP (from_string)
9110                           && (string = POSN_STRING (EVENT_START (key)),
9111                               (CONSP (string) && STRINGP (XCAR (string)))))
9112                    {
9113                      /* For a click on a string, i.e. overlay string or a
9114                         string displayed via the `display' property,
9115                         consider `local-map' and `keymap' properties of
9116                         that string.  */
9117                      Lisp_Object pos, map, map2;
9118    
9119                      pos = XCDR (string);
9120                      string = XCAR (string);
9121                      if (XINT (pos) >= 0
9122                          && XINT (pos) < SCHARS (string))
9123                        {
9124                          map = Fget_text_property (pos, Qlocal_map, 
string);
9125                          if (!NILP (map))
9126                            orig_local_map = map;
9127                          map2 = Fget_text_property (pos, Qkeymap, string);
9128                          if (!NILP (map2))
9129                            orig_keymap = map2;
9130    
9131                          if (!NILP (map) || !NILP (map2))
9132                            {
9133                              from_string = string;
9134                              goto replay_sequence;
9135                            }
9136                        }
9137                    }
9138                }
9139              else if (CONSP (XCDR (key))
9140                       && CONSP (EVENT_START (key))
9141                       && CONSP (XCDR (EVENT_START (key))))
9142                {
9143                  Lisp_Object posn;
9144    
9145                  posn = POSN_POSN (EVENT_START (key));
9146                  /* Handle menu-bar events:
9147                     insert the dummy prefix event `menu-bar'.  */
9148                  if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar))
9149                    {
9150                      if (t + 1 >= bufsize)
9151                        error ("Key sequence too long");
9152                      keybuf[t] = posn;
9153                      keybuf[t+1] = key;
9154    
9155                      /* Zap the position in key, so we know that we've
9156                         expanded it, and don't try to do so again.  */
9157                      POSN_SET_POSN (EVENT_START (key),
9158                                     Fcons (posn, Qnil));
9159    
9160                      mock_input = t + 2;
9161                      goto replay_sequence;
9162                    }
9163                  else if (CONSP (posn))
9164                    {
9165                      /* We're looking at the second event of a
9166                         sequence which we expanded before.  Set
9167                         last_real_key_start appropriately.  */
9168                      if (last_real_key_start == t && t > 0)
9169                        last_real_key_start = t - 1;
9170                    }
9171                }
9172            }
9173    
9174          /* We have finally decided that KEY is something we might want
9175             to look up.  */
9176          first_binding = (follow_key (key,
9177                                       nmaps   - first_binding,
9178                                       submaps + first_binding,
9179                                       defs    + first_binding,
9180                                       submaps + first_binding)
9181                           + first_binding);
9182    
9183          /* If KEY wasn't bound, we'll try some fallbacks.  */
9184          if (first_binding < nmaps)
9185            /* This is needed for the following scenario:
9186               event 0: a down-event that gets dropped by calling 
replay_key.
9187               event 1: some normal prefix like C-h.
9188               After event 0, first_unbound is 0, after event 1 fkey.start
9189               and keytran.start are both 1, so when we see that C-h is 
bound,
9190               we need to update first_unbound.  */
9191            first_unbound = max (t + 1, first_unbound);
9192          else
9193            {
9194              Lisp_Object head;
9195    
9196              /* Remember the position to put an upper bound on fkey.start. 
 */
9197              first_unbound = min (t, first_unbound);
9198    
9199              head = EVENT_HEAD (key);
9200              if (help_char_p (head) && t > 0)
9201                {
9202                  read_key_sequence_cmd = Vprefix_help_command;
9203                  keybuf[t++] = key;
9204                  last_nonmenu_event = key;
9205                  /* The Microsoft C compiler can't handle the goto that
9206                     would go here.  */
9207                  dummyflag = 1;
9208                  break;
9209                }
9210    
9211              if (SYMBOLP (head))
9212                {
9213                  Lisp_Object breakdown;
9214                  int modifiers;
9215    
9216                  breakdown = parse_modifiers (head);
9217                  modifiers = XINT (XCAR (XCDR (breakdown)));
9218                  /* Attempt to reduce an unbound mouse event to a simpler
9219                     event that is bound:
9220                       Drags reduce to clicks.
9221                       Double-clicks reduce to clicks.
9222                       Triple-clicks reduce to double-clicks, then to 
clicks.
9223                       Down-clicks are eliminated.
9224                       Double-downs reduce to downs, then are eliminated.
9225                       Triple-downs reduce to double-downs, then to downs,
9226                         then are eliminated. */
9227                  if (modifiers & (down_modifier | drag_modifier
9228                                   | double_modifier | triple_modifier))
9229                    {
9230                      while (modifiers & (down_modifier | drag_modifier
9231                                          | double_modifier | 
triple_modifier))
9232                        {
9233                          Lisp_Object new_head, new_click;
9234                          if (modifiers & triple_modifier)
9235                            modifiers ^= (double_modifier | 
triple_modifier);
9236                          else if (modifiers & double_modifier)
9237                            modifiers &= ~double_modifier;
9238                          else if (modifiers & drag_modifier)
9239                            modifiers &= ~drag_modifier;
9240                          else
9241                            {
9242                              /* Dispose of this `down' event by simply 
jumping
9243                                 back to replay_key, to get another event.
9244    
9245                                 Note that if this event came from mock 
input,
9246                                 then just jumping back to replay_key will 
just
9247                                 hand it to us again.  So we have to wipe 
out any
9248                                 mock input.
9249    
9250                                 We could delete keybuf[t] and shift 
everything
9251                                 after that to the left by one spot, but 
we'd also
9252                                 have to fix up any variable that points 
into
9253                                 keybuf, and shifting isn't really necessary
9254                                 anyway.
9255    
9256                                 Adding prefixes for non-textual mouse 
clicks
9257                                 creates two characters of mock input, and 
both
9258                                 must be thrown away.  If we're only 
looking at
9259                                 the prefix now, we can just jump back to
9260                                 replay_key.  On the other hand, if we've 
already
9261                                 processed the prefix, and now the actual 
click
9262                                 itself is giving us trouble, then we've 
lost the
9263                                 state of the keymaps we want to backtrack 
to, and
9264                                 we need to replay the whole sequence to 
rebuild
9265                                 it.
9266    
9267                                 Beyond that, only function key expansion 
could
9268                                 create more than two keys, but that should 
never
9269                                 generate mouse events, so it's okay to zero
9270                                 mock_input in that case too.
9271    
9272                                 FIXME: The above paragraph seems just plain
9273                                 wrong, if you consider things like
9274                                 xterm-mouse-mode.  -stef
9275    
9276                                 Isn't this just the most wonderful code 
ever?  */
9277    
9278                              /* If mock_input > t + 1, the above 
simplification
9279                                 will actually end up dropping keys on the 
floor.
9280                                 This is probably OK for now, but even
9281                                 if mock_input <= t + 1, we need to adjust 
fkey
9282                                 and keytran.
9283                                 Typical case [header-line down-mouse-N]:
9284                                 mock_input = 2, t = 1, fkey.end = 1,
9285                                 last_real_key_start = 0.  */
9286                              if (fkey.end > last_real_key_start)
9287                                {
9288                                  fkey.end = fkey.start
9289                                    = min (last_real_key_start, fkey.start);
9290                                  fkey.map = fkey.parent;
9291                                  if (keytran.end > last_real_key_start)
9292                                    {
9293                                      keytran.end = keytran.start
9294                                        = min (last_real_key_start, 
keytran.start);
9295                                      keytran.map = keytran.parent;
9296                                    }
9297                                }
9298                              if (t == last_real_key_start)
9299                                {
9300                                  mock_input = 0;
9301                                  goto replay_key;
9302                                }
9303                              else
9304                                {
9305                                  mock_input = last_real_key_start;
9306                                  goto replay_sequence;
9307                                }
9308                            }
9309    
9310                          new_head
9311                            = apply_modifiers (modifiers, XCAR (breakdown));
9312                          new_click
9313                            = Fcons (new_head, Fcons (EVENT_START (key), 
Qnil));
9314    
9315                          /* Look for a binding for this new key.  
follow_key
9316                             promises that it didn't munge submaps the
9317                             last time we called it, since key was unbound. 
 */
9318                          first_binding
9319                            = (follow_key (new_click,
9320                                           nmaps   - local_first_binding,
9321                                           submaps + local_first_binding,
9322                                           defs    + local_first_binding,
9323                                           submaps + local_first_binding)
9324                               + local_first_binding);
9325    
9326                          /* If that click is bound, go for it.  */
9327                          if (first_binding < nmaps)
9328                            {
9329                              key = new_click;
9330                              break;
9331                            }
9332                          /* Otherwise, we'll leave key set to the drag 
event.  */
9333                        }
9334                    }
9335                }
9336            }
9337    
9338          keybuf[t++] = key;
9339          /* Normally, last_nonmenu_event gets the previous key we read.
9340             But when a mouse popup menu is being used,
9341             we don't update last_nonmenu_event; it continues to hold the 
mouse
9342             event that preceded the first level of menu.  */
9343          if (!used_mouse_menu)
9344            last_nonmenu_event = key;
9345    
9346          /* Record what part of this_command_keys is the current key 
sequence.  */
9347          this_single_command_key_start = this_command_key_count - t;
9348    
9349          if (first_binding < nmaps && NILP (submaps[first_binding]))
9350            /* There is a binding and it's not a prefix.
9351               There is thus no function-key in this sequence.
9352               Moving fkey.start is important in this case to allow 
keytran.start
9353               to go over the sequence before we return (since we keep the
9354               invariant that keytran.end <= fkey.start).  */
9355            {
9356              if (fkey.start < t)
9357                (fkey.start = fkey.end = t, fkey.map = fkey.parent);
9358            }
9359          else
9360            /* If the sequence is unbound, see if we can hang a function key
9361               off the end of it.  */
9362            /* Continue scan from fkey.end until we find a bound suffix.  */
9363            while (fkey.end < t)
9364              {
9365                struct gcpro gcpro1, gcpro2, gcpro3;
9366                int done, diff;
9367    
9368                GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
9369                done = keyremap_step (keybuf, bufsize, &fkey,
9370                                      max (t, mock_input),
9371                                      /* If there's a binding (i.e.
9372                                         first_binding >= nmaps) we don't 
want
9373                                         to apply this 
function-key-mapping.  */
9374                                      fkey.end + 1 == t && first_binding >= 
nmaps,
9375                                      &diff, prompt);
9376                UNGCPRO;
9377                if (done)
9378                  {
9379                    mock_input = diff + max (t, mock_input);
9380                    goto replay_sequence;
9381                  }
9382              }
9383    
9384          /* Look for this sequence in key-translation-map.
9385             Scan from keytran.end until we find a bound suffix.  */
9386          while (keytran.end < fkey.start)
9387            {
9388              struct gcpro gcpro1, gcpro2, gcpro3;
9389              int done, diff;
9390    
9391              GCPRO3 (fkey.map, keytran.map, delayed_switch_frame);
9392              done = keyremap_step (keybuf, bufsize, &keytran, max (t, 
mock_input),
9393                                    1, &diff, prompt);
9394              UNGCPRO;
9395              if (done)
9396                {
9397                  mock_input = diff + max (t, mock_input);
9398                  /* Adjust the function-key-map counters.  */
9399                  fkey.end += diff;
9400                  fkey.start += diff;
9401    
9402                  goto replay_sequence;
9403                }
9404            }
9405    
9406          /* If KEY is not defined in any of the keymaps,
9407             and cannot be part of a function key or translation,
9408             and is an upper case letter
9409             use the corresponding lower-case letter instead.  */
9410          if (first_binding >= nmaps
9411              && fkey.start >= t && keytran.start >= t
9412              && INTEGERP (key)
9413              && ((((XINT (key) & 0x3ffff)
9414                    < XCHAR_TABLE (current_buffer->downcase_table)->size)
9415                   && UPPERCASEP (XINT (key) & 0x3ffff))
9416                  || (XINT (key) & shift_modifier)))
9417            {
9418              Lisp_Object new_key;
9419    
9420              original_uppercase = key;
9421              original_uppercase_position = t - 1;
9422    
9423              if (XINT (key) & shift_modifier)
9424                XSETINT (new_key, XINT (key) & ~shift_modifier);
9425              else
9426                XSETINT (new_key, (DOWNCASE (XINT (key) & 0x3ffff)
9427                                   | (XINT (key) & ~0x3ffff)));
9428    
9429              /* We have to do this unconditionally, regardless of whether
9430                 the lower-case char is defined in the keymaps, because they
9431                 might get translated through function-key-map.  */
9432              keybuf[t - 1] = new_key;
9433              mock_input = max (t, mock_input);
9434    
9435              goto replay_sequence;
9436            }
9437          /* If KEY is not defined in any of the keymaps,
9438             and cannot be part of a function key or translation,
9439             and is a shifted function key,
9440             use the corresponding unshifted function key instead.  */
9441          if (first_binding >= nmaps
9442              && fkey.start >= t && keytran.start >= t
9443              && SYMBOLP (key))
9444            {
9445              Lisp_Object breakdown;
9446              int modifiers;
9447    
9448              breakdown = parse_modifiers (key);
9449              modifiers = XINT (XCAR (XCDR (breakdown)));
9450              if (modifiers & shift_modifier)
9451                {
9452                  Lisp_Object new_key;
9453    
9454                  original_uppercase = key;
9455                  original_uppercase_position = t - 1;
9456    
9457                  modifiers &= ~shift_modifier;
9458                  new_key = apply_modifiers (modifiers,
9459                                             XCAR (breakdown));
9460    
9461                  keybuf[t - 1] = new_key;
9462                  mock_input = max (t, mock_input);
9463                  fkey.start = fkey.end = KEYMAPP (fkey.map) ? 0 : bufsize 
+ 1;
9464                  keytran.start = keytran.end = KEYMAPP (keytran.map) ? 0 : 
bufsize + 1;
9465    
9466                  goto replay_sequence;
9467                }
9468            }
9469        }
9470    

At conditional (19): "dummyflag == 0" taking false path

9471      if (!dummyflag)
9472        read_key_sequence_cmd = (first_binding < nmaps
9473                                 ? defs[first_binding]
9474                                 : Qnil);
9475    
9476      unread_switch_frame = delayed_switch_frame;
9477      unbind_to (count, Qnil);
9478    
9479      /* Don't downcase the last character if the caller says don't.
9480         Don't downcase it if the result is undefined, either.  */

At conditional (20): "dont_downcase_last != 0" taking true path
At conditional (21): "(t - 1) == original_uppercase_position" taking true path

9481      if ((dont_downcase_last || first_binding >= nmaps)
9482          && t - 1 == original_uppercase_position)

Event uninit_use: Using uninitialized value "original_uppercase"
Also see events: [var_decl]

9483        keybuf[t - 1] = original_uppercase;
9484    




reply via email to

[Prev in Thread] Current Thread [Next in Thread]