Coverage Report

Created: 2026-10-17 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/barebox/lib/readkey.c
Line
Count
Source
1
/*
2
 * readkey.c - read keystrokes and decode standard escape sequences
3
 *
4
 * Partly based on busybox vi
5
 *
6
 * Copyright (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License version 2
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 */
18
19
#include <common.h>
20
#include <clock.h>
21
#include <linux/ktime.h>
22
#include <linux/ctype.h>
23
#include <readkey.h>
24
25
struct esc_cmds {
26
  const char *seq;
27
  unsigned char val;
28
};
29
30
static const struct esc_cmds esccmds[] = {
31
  {"OA", BB_KEY_UP},       // cursor key Up
32
  {"OB", BB_KEY_DOWN},     // cursor key Down
33
  {"OC", BB_KEY_RIGHT},    // Cursor Key Right
34
  {"OD", BB_KEY_LEFT},     // cursor key Left
35
  {"OH", BB_KEY_HOME},     // Cursor Key Home
36
  {"OF", BB_KEY_END},      // Cursor Key End
37
  {"[A", BB_KEY_UP},       // cursor key Up
38
  {"[B", BB_KEY_DOWN},     // cursor key Down
39
  {"[C", BB_KEY_RIGHT},    // Cursor Key Right
40
  {"[D", BB_KEY_LEFT},     // cursor key Left
41
  {"[H", BB_KEY_HOME},     // Cursor Key Home
42
  {"[F", BB_KEY_END},      // Cursor Key End
43
  {"[1~", BB_KEY_HOME},    // Cursor Key Home
44
  {"[2~", BB_KEY_INSERT},  // Cursor Key Insert
45
  {"[3~", BB_KEY_DEL},     // Cursor Key Delete
46
  {"[4~", BB_KEY_END},     // Cursor Key End
47
  {"[5~", BB_KEY_PAGEUP},  // Cursor Key Page Up
48
  {"[6~", BB_KEY_PAGEDOWN},// Cursor Key Page Down
49
};
50
51
static int poll_key_into_buf(unsigned char *key)
52
0
{
53
0
  int ret;
54
55
0
  ret = pollchar(50 * MSECOND);
56
0
  if (ret < 0)
57
0
    return ret;
58
59
0
  *key = ret;
60
0
  return 0;
61
0
}
62
63
int read_key(void)
64
0
{
65
0
  unsigned char c;
66
0
  unsigned char esc[5];
67
0
  c = getchar();
68
69
0
  if (c == 27) {
70
0
    int i = 0;
71
72
    /*
73
     * Escape sequences (arrow keys, etc.) arrive as a burst
74
     * of characters: ESC [ A, ESC [ 1 ~ etc.  A standalone
75
     * ESC keypress sends just the single 0x1b byte.
76
     *
77
     * Wait briefly for a follow-up character; if nothing
78
     * arrives it was a bare ESC.
79
     */
80
0
    if (poll_key_into_buf(&esc[i++]))
81
0
      return '\e';
82
83
0
    if (poll_key_into_buf(&esc[i++]))
84
0
      return -1;
85
86
0
    if (isdigit(esc[1])) {
87
0
      while(1) {
88
0
        esc[i] = getchar();
89
0
        if (esc[i++] == '~')
90
0
          break;
91
0
        if (i == ARRAY_SIZE(esc) - 1)
92
0
          return -1;
93
0
      }
94
0
    }
95
0
    esc[i] = 0;
96
0
    for (i = 0; i < ARRAY_SIZE(esccmds); i++){
97
0
      if (!strcmp(esc, esccmds[i].seq))
98
0
        return esccmds[i].val;
99
0
    }
100
0
    return -1;
101
0
  }
102
0
  return c;
103
0
}
104
EXPORT_SYMBOL(read_key);