|
Packit |
db01ca |
/* -*- linux-c -*-
|
|
Packit |
db01ca |
*
|
|
Packit |
db01ca |
* Copyright (c) 2005 by Intel Corp.
|
|
Packit |
db01ca |
*
|
|
Packit |
db01ca |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
db01ca |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
db01ca |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This
|
|
Packit |
db01ca |
* file and program are licensed under a BSD style license. See
|
|
Packit |
db01ca |
* the Copying file included with the OpenHPI distribution for
|
|
Packit |
db01ca |
* full licensing terms.
|
|
Packit |
db01ca |
*
|
|
Packit |
db01ca |
* Author(s):
|
|
Packit |
db01ca |
* Kouzmich < Mikhail.V.Kouzmich@intel.com >
|
|
Packit |
db01ca |
*
|
|
Packit |
db01ca |
*
|
|
Packit |
db01ca |
*/
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
#include <stdio.h>
|
|
Packit |
db01ca |
#include <stdlib.h>
|
|
Packit |
db01ca |
#include <string.h>
|
|
Packit |
db01ca |
#include <time.h>
|
|
Packit |
db01ca |
#include <ctype.h>
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
#ifdef _WIN32
|
|
Packit |
db01ca |
// TODO
|
|
Packit |
db01ca |
#else
|
|
Packit |
db01ca |
#include <fcntl.h>
|
|
Packit |
db01ca |
#include <termios.h>
|
|
Packit |
db01ca |
#endif
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
#include "hpi_cmd.h"
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
#define CTRL_A_KEY 0x01
|
|
Packit |
db01ca |
#define CTRL_B_KEY 0x02
|
|
Packit |
db01ca |
#define CTRL_D_KEY 0x04
|
|
Packit |
db01ca |
#define CTRL_E_KEY 0x05
|
|
Packit |
db01ca |
#define CTRL_F_KEY 0x06
|
|
Packit |
db01ca |
#define CTRL_G_KEY 0x07
|
|
Packit |
db01ca |
#define BELL_KEY 0x07
|
|
Packit |
db01ca |
#define CTRL_H_KEY 0x08
|
|
Packit |
db01ca |
#define TAB_KEY 0x09
|
|
Packit |
db01ca |
#define NL_KEY 0x0A
|
|
Packit |
db01ca |
#define CTRL_K_KEY 0x0B
|
|
Packit |
db01ca |
#define CTRL_L_KEY 0x0C
|
|
Packit |
db01ca |
#define CTRL_N_KEY 0x0E
|
|
Packit |
db01ca |
#define CTRL_R_KEY 0x12
|
|
Packit |
db01ca |
#define CTRL_S_KEY 0x13
|
|
Packit |
db01ca |
#define CTRL1_KEY 0x1B
|
|
Packit |
db01ca |
#define CTRL2_KEY 0x5B
|
|
Packit |
db01ca |
#define BACKSP_KEY 0x7F
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
#define INSERT_KEY 0x32
|
|
Packit |
db01ca |
#define DELETE_KEY 0x33
|
|
Packit |
db01ca |
#define PGUP_KEY 0x35
|
|
Packit |
db01ca |
#define PGDOWN_KEY 0x36
|
|
Packit |
db01ca |
#define UP_KEY 0x41
|
|
Packit |
db01ca |
#define DOWN_KEY 0x42
|
|
Packit |
db01ca |
#define RIGHT_KEY 0x43
|
|
Packit |
db01ca |
#define LEFT_KEY 0x44
|
|
Packit |
db01ca |
#define END_KEY 0x46
|
|
Packit |
db01ca |
#define HOME_KEY 0x48
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
#define HISTORY_DELTA 5
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
typedef struct {
|
|
Packit |
db01ca |
int n_items;
|
|
Packit |
db01ca |
int comp_len;
|
|
Packit |
db01ca |
char **items;
|
|
Packit |
db01ca |
} compl_t;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
compl_t complition_struct;
|
|
Packit |
db01ca |
int termfd = -1;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static char clear_buf[READ_BUF_SIZE];
|
|
Packit |
db01ca |
static int no_stty = 1;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
#ifdef _WIN32
|
|
Packit |
db01ca |
// TODO
|
|
Packit |
db01ca |
#else
|
|
Packit |
db01ca |
static struct termios saved_termio;
|
|
Packit |
db01ca |
#endif
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static int is_insert_key = 0;
|
|
Packit |
db01ca |
static char **History;
|
|
Packit |
db01ca |
static int hist_ind = 0;
|
|
Packit |
db01ca |
static int hist_size = 0;
|
|
Packit |
db01ca |
static int current_hist_ind = -1;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
void init_history(void)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
History = (char **)malloc(sizeof(char *) * HISTORY_DELTA);
|
|
Packit |
db01ca |
hist_size = HISTORY_DELTA;
|
|
Packit |
db01ca |
memset(History, 0, sizeof(char *) * HISTORY_DELTA);
|
|
Packit |
db01ca |
current_hist_ind = -1;
|
|
Packit |
db01ca |
hist_ind = 0;
|
|
Packit |
db01ca |
complition_struct.n_items = 0;
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static void get_history_new(int new_cmd)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
char **tmp;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
if (current_hist_ind < 0) new_cmd = 1;
|
|
Packit |
db01ca |
if ((current_hist_ind >= 0) &&
|
|
Packit |
db01ca |
(*(History[current_hist_ind]) == 0)) {
|
|
Packit |
db01ca |
hist_ind = current_hist_ind;
|
|
Packit |
db01ca |
return;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
if (new_cmd) current_hist_ind++;
|
|
Packit |
db01ca |
else return;
|
|
Packit |
db01ca |
if (current_hist_ind >= hist_size) {
|
|
Packit |
db01ca |
hist_size += HISTORY_DELTA;
|
|
Packit |
db01ca |
tmp = (char **)malloc(sizeof(char *) * hist_size);
|
|
Packit |
db01ca |
memset(tmp, 0, sizeof(char *) * hist_size);
|
|
Packit |
db01ca |
if (current_hist_ind > 1) {
|
|
Packit |
db01ca |
memcpy(tmp, History,
|
|
Packit |
db01ca |
sizeof(char *) * current_hist_ind);
|
|
Packit |
db01ca |
free(History);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
History = tmp;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
hist_ind = current_hist_ind;
|
|
Packit |
db01ca |
History[current_hist_ind] = (char *)malloc(1);
|
|
Packit |
db01ca |
*(History[current_hist_ind]) = 0;
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static void add_to_history(char *line, int index)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
if (line == (char *)NULL) return;
|
|
Packit |
db01ca |
if (strlen(line) == 0) return;
|
|
Packit |
db01ca |
if (index > current_hist_ind) return;
|
|
Packit |
db01ca |
if(strcmp(line, History[index]) == 0) return;
|
|
Packit |
db01ca |
free(History[index]);
|
|
Packit |
db01ca |
History[index] = strdup(line);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static char *get_history_next(char *str)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
add_to_history(str, hist_ind);
|
|
Packit |
db01ca |
if (current_hist_ind > hist_ind) hist_ind++;
|
|
Packit |
db01ca |
else printf("%c", BELL_KEY);
|
|
Packit |
db01ca |
return(History[hist_ind]);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static char *get_history_prev(char *str)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
add_to_history(str, hist_ind);
|
|
Packit |
db01ca |
hist_ind--;
|
|
Packit |
db01ca |
if (hist_ind < 0) {
|
|
Packit |
db01ca |
hist_ind = 0;
|
|
Packit |
db01ca |
printf("%c", BELL_KEY);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
return(History[hist_ind]);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static void go_to_begin(int index)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
while (index-- > 0) printf("%c", '\b');
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static int print_str_by_index(char *buf, int index, int cursor_pos)
|
|
Packit |
db01ca |
// index - current cursor position
|
|
Packit |
db01ca |
// cursor_pos - new cursor position,
|
|
Packit |
db01ca |
// if cursor_pos == -1 set to the end of the buf
|
|
Packit |
db01ca |
// return value: new cursor position
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
int n;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
n = strlen(buf) - index;
|
|
Packit |
db01ca |
if (n > 0)
|
|
Packit |
db01ca |
printf("%s", buf + index);
|
|
Packit |
db01ca |
if ((cursor_pos == -1) || (cursor_pos > strlen(buf)))
|
|
Packit |
db01ca |
cursor_pos = strlen(buf);
|
|
Packit |
db01ca |
n = strlen(buf) - cursor_pos;
|
|
Packit |
db01ca |
go_to_begin(n);
|
|
Packit |
db01ca |
return(cursor_pos);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static int clear_line(int index, int length)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
go_to_begin(index);
|
|
Packit |
db01ca |
memset(clear_buf, ' ', length);
|
|
Packit |
db01ca |
clear_buf[length] = 0;
|
|
Packit |
db01ca |
return(print_str_by_index(clear_buf, 0, 0));
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static int add_char(char *buf, int length, int c, int index)
|
|
Packit |
db01ca |
// return value : new corsor position
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
int i;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
if (index >= length) {
|
|
Packit |
db01ca |
buf[length++] = c;
|
|
Packit |
db01ca |
return(length);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
if ( ! is_insert_key)
|
|
Packit |
db01ca |
for (i = length; i > index; i--) buf[i] = buf[i - 1];
|
|
Packit |
db01ca |
buf[index] = c;
|
|
Packit |
db01ca |
i = (is_insert_key) ? length - 1 : length;
|
|
Packit |
db01ca |
print_str_by_index(buf, index, index + 1);
|
|
Packit |
db01ca |
return(index + 1);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static int delete_char(char *buf, int length, int index, int as)
|
|
Packit |
db01ca |
// as = 0 - backspace key, 1 - delete key
|
|
Packit |
db01ca |
// return value : new corsor position
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
int n, ind;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
if (index < 0) return(0);
|
|
Packit |
db01ca |
if ((index == length) && as) return(length);
|
|
Packit |
db01ca |
ind = (as) ? index : index - 1;
|
|
Packit |
db01ca |
memcpy(buf + ind, buf + ind + 1, length - ind - 1);
|
|
Packit |
db01ca |
buf[length - 1] = ' ';
|
|
Packit |
db01ca |
if (as == 0) printf("%c", '\b');
|
|
Packit |
db01ca |
n = print_str_by_index(buf, ind, ind);
|
|
Packit |
db01ca |
buf[length - 1] = 0;
|
|
Packit |
db01ca |
return(n);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static int find_cmd_by_text(char *text, int current_index, int forward)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
int i, len, is_cmp = 0;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
len = strlen(text);
|
|
Packit |
db01ca |
if (len == 0) return(-1);
|
|
Packit |
db01ca |
for (i = current_index; (i >= 0) && (i <= current_hist_ind);) {
|
|
Packit |
db01ca |
if (strncmp(History[i], text, len) == 0) {
|
|
Packit |
db01ca |
is_cmp = 1;
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
if (forward) i++;
|
|
Packit |
db01ca |
else i--;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
if (is_cmp) return(i);
|
|
Packit |
db01ca |
return(-1);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static int find_command(char *line, int curr_index, int forward)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
int res, cmd_ind, len, ind, c, line_size;
|
|
Packit |
db01ca |
char str[READ_BUF_SIZE];
|
|
Packit |
db01ca |
char text[READ_BUF_SIZE];
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
len = strlen(line) + strlen(Title);
|
|
Packit |
db01ca |
clear_line(len, len);
|
|
Packit |
db01ca |
if (forward) {
|
|
Packit |
db01ca |
if (curr_index == current_hist_ind) {
|
|
Packit |
db01ca |
printf("%c", BELL_KEY);
|
|
Packit |
db01ca |
return(curr_index);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
} else {
|
|
Packit |
db01ca |
if (curr_index <= 0) {
|
|
Packit |
db01ca |
printf("%c", BELL_KEY);
|
|
Packit |
db01ca |
return(0);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
memset(text, 0, READ_BUF_SIZE);
|
|
Packit |
db01ca |
len = 0;
|
|
Packit |
db01ca |
ind = 0;
|
|
Packit |
db01ca |
cmd_ind = curr_index;
|
|
Packit |
db01ca |
for (;;) {
|
|
Packit |
db01ca |
line_size = ind + strlen(History[cmd_ind]);
|
|
Packit |
db01ca |
if (forward)
|
|
Packit |
db01ca |
res = find_cmd_by_text(text, cmd_ind, 1);
|
|
Packit |
db01ca |
else
|
|
Packit |
db01ca |
res = find_cmd_by_text(text, cmd_ind, 0);
|
|
Packit |
db01ca |
if (res != -1)
|
|
Packit |
db01ca |
cmd_ind = res;
|
|
Packit |
db01ca |
else
|
|
Packit |
db01ca |
printf("%c", BELL_KEY);
|
|
Packit |
db01ca |
if (forward)
|
|
Packit |
db01ca |
snprintf(str, READ_BUF_SIZE,
|
|
Packit |
db01ca |
"(i-search)`%s': ", text);
|
|
Packit |
db01ca |
else
|
|
Packit |
db01ca |
snprintf(str, READ_BUF_SIZE,
|
|
Packit |
db01ca |
"(revers-i-search)`%s': ", text);
|
|
Packit |
db01ca |
clear_line(ind, line_size);
|
|
Packit |
db01ca |
ind = print_str_by_index(str, 0, -1);
|
|
Packit |
db01ca |
print_str_by_index(History[cmd_ind], 0, 0);
|
|
Packit |
db01ca |
c = getchar();
|
|
Packit |
db01ca |
if (c == BACKSP_KEY) {
|
|
Packit |
db01ca |
len--;
|
|
Packit |
db01ca |
if (len < 0) len = 0;
|
|
Packit |
db01ca |
text[len] = 0;
|
|
Packit |
db01ca |
} else if ((c < ' ') || (c > 'z')) {
|
|
Packit |
db01ca |
ungetc(c, stdin);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
text[len++] = c;
|
|
Packit |
db01ca |
if (len >= READ_BUF_SIZE) break;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
res = ind + strlen(History[cmd_ind]);
|
|
Packit |
db01ca |
clear_line(ind, res);
|
|
Packit |
db01ca |
return(cmd_ind);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static void check_compl(compl_t *compl_def)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
int i, j, len;
|
|
Packit |
db01ca |
char *str;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
if (compl_def->n_items == 0) {
|
|
Packit |
db01ca |
compl_def->comp_len = 0;
|
|
Packit |
db01ca |
return;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
if (compl_def->n_items == 1) {
|
|
Packit |
db01ca |
compl_def->comp_len = strlen(compl_def->items[0]);
|
|
Packit |
db01ca |
return;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
str = compl_def->items[0];
|
|
Packit |
db01ca |
len = strlen(str);
|
|
Packit |
db01ca |
for (i = 1; i < compl_def->n_items; i++) {
|
|
Packit |
db01ca |
for (j = len; j > 0; j--) {
|
|
Packit |
db01ca |
if (strncmp(str, compl_def->items[i], j) == 0)
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
if (j == 0) {
|
|
Packit |
db01ca |
compl_def->comp_len = 0;
|
|
Packit |
db01ca |
return;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
len = j;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
compl_def->comp_len = len;
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static void add_to_compl(char *text, compl_t *compl_def)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
char **tmp;
|
|
Packit |
db01ca |
int n;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
n = compl_def->n_items + 1;
|
|
Packit |
db01ca |
tmp = (char **)malloc(sizeof(char *) * n);
|
|
Packit |
db01ca |
if (compl_def->n_items > 0) {
|
|
Packit |
db01ca |
memcpy(tmp, compl_def->items,
|
|
Packit |
db01ca |
sizeof(char *) * compl_def->n_items);
|
|
Packit |
db01ca |
free(compl_def->items);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
compl_def->items = tmp;
|
|
Packit |
db01ca |
tmp[compl_def->n_items] = strdup(text);
|
|
Packit |
db01ca |
compl_def->n_items = n;
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static int completion_func(int compl_type, char *text, compl_t *compl_def)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
int i, len;
|
|
Packit |
db01ca |
command_def_t *cmd = NULL;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
if (compl_def == (compl_t *)NULL) return(0);
|
|
Packit |
db01ca |
if (compl_def->n_items > 0) {
|
|
Packit |
db01ca |
for (i = 0; i < compl_def->n_items; i++)
|
|
Packit |
db01ca |
free(compl_def->items[i]);
|
|
Packit |
db01ca |
free(compl_def->items);
|
|
Packit |
db01ca |
compl_def->n_items = 0;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
compl_def->comp_len = 0;
|
|
Packit |
db01ca |
len = strlen(text);
|
|
Packit |
db01ca |
switch (compl_type) {
|
|
Packit |
db01ca |
case COMPL_CMD:
|
|
Packit |
db01ca |
for (cmd = commands; cmd->cmd != NULL; cmd++) {
|
|
Packit |
db01ca |
if ((cmd->type != MAIN_COM) &&
|
|
Packit |
db01ca |
(cmd->type != block_type) &&
|
|
Packit |
db01ca |
(cmd->type != UNDEF_COM))
|
|
Packit |
db01ca |
continue;
|
|
Packit |
db01ca |
if (strncmp(text, cmd->cmd, len) == 0)
|
|
Packit |
db01ca |
add_to_compl(cmd->cmd, compl_def);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case COMPL_NULL:
|
|
Packit |
db01ca |
return(0);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
check_compl(compl_def);
|
|
Packit |
db01ca |
return(compl_def->n_items);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
static int set_term_flags(void)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
#ifdef _WIN32
|
|
Packit |
db01ca |
// TODO
|
|
Packit |
db01ca |
return 0;
|
|
Packit |
db01ca |
#else
|
|
Packit |
db01ca |
int res, c;
|
|
Packit |
db01ca |
char name[1024];
|
|
Packit |
db01ca |
struct termios termio;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
if (no_stty == 0) return(0);
|
|
Packit |
db01ca |
ctermid(name);
|
|
Packit |
db01ca |
termfd = open(name, O_RDWR);
|
|
Packit |
db01ca |
if (termfd < 0) {
|
|
Packit |
db01ca |
printf("Can not open terminal\n");
|
|
Packit |
db01ca |
return(1);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
c = tcgetattr(termfd, &saved_termio);
|
|
Packit |
db01ca |
if (c != 0) {
|
|
Packit |
db01ca |
printf("Can not read terminal attrs\n");
|
|
Packit |
db01ca |
return(1);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
termio = saved_termio;
|
|
Packit |
db01ca |
c = ICANON | ECHO | ECHOCTL;
|
|
Packit |
db01ca |
c = ~c;
|
|
Packit |
db01ca |
termio.c_lflag &= c;
|
|
Packit |
db01ca |
termio.c_cc[VMIN] = 1;
|
|
Packit |
db01ca |
termio.c_cc[VTIME] = 0;
|
|
Packit |
db01ca |
res = tcsetattr(termfd, TCSANOW, &termio);
|
|
Packit |
db01ca |
no_stty = 0;
|
|
Packit |
db01ca |
return(res);
|
|
Packit |
db01ca |
#endif
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
void restore_term_flags(void)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
#ifdef _WIN32
|
|
Packit |
db01ca |
// TODO
|
|
Packit |
db01ca |
#else
|
|
Packit |
db01ca |
if (no_stty) return;
|
|
Packit |
db01ca |
tcsetattr(termfd, TCSANOW, &saved_termio);
|
|
Packit |
db01ca |
no_stty = 1;
|
|
Packit |
db01ca |
#endif
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
char *get_command_line(int new_cmd, int comp_type)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
int c, ind = 0, len = 0, res;
|
|
Packit |
db01ca |
char input_buf[READ_BUF_SIZE];
|
|
Packit |
db01ca |
char *str;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
if (set_term_flags() != 0)
|
|
Packit |
db01ca |
exit(1);
|
|
Packit |
db01ca |
get_history_new(new_cmd);
|
|
Packit |
db01ca |
memset(input_buf, 0, READ_BUF_SIZE);
|
|
Packit |
db01ca |
for (;;) {
|
|
Packit |
db01ca |
c = getchar();
|
|
Packit |
db01ca |
len = strlen(input_buf);
|
|
Packit |
db01ca |
if (len >= (READ_BUF_SIZE - 1)) c = NL_KEY;
|
|
Packit |
db01ca |
switch (c) {
|
|
Packit |
db01ca |
case CTRL_A_KEY:
|
|
Packit |
db01ca |
go_to_begin(ind);
|
|
Packit |
db01ca |
ind = print_str_by_index(input_buf, 0, 0);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case CTRL_B_KEY:
|
|
Packit |
db01ca |
printf("%c", '\b');
|
|
Packit |
db01ca |
ind--;
|
|
Packit |
db01ca |
if (ind < 0) {
|
|
Packit |
db01ca |
ind = 0;
|
|
Packit |
db01ca |
printf("%c", ' ');
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case CTRL_D_KEY:
|
|
Packit |
db01ca |
if (ind == len) break;
|
|
Packit |
db01ca |
ind = delete_char(input_buf, len, ind, 1);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case CTRL_E_KEY:
|
|
Packit |
db01ca |
ind = print_str_by_index(input_buf, ind, len);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case CTRL_G_KEY:
|
|
Packit |
db01ca |
case CTRL_L_KEY:
|
|
Packit |
db01ca |
printf("%c", c);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case CTRL_F_KEY:
|
|
Packit |
db01ca |
ind = print_str_by_index(input_buf, ind, ind + 1);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case TAB_KEY:
|
|
Packit |
db01ca |
res = completion_func(comp_type, input_buf,
|
|
Packit |
db01ca |
&complition_struct);
|
|
Packit |
db01ca |
if (res == 0) break;
|
|
Packit |
db01ca |
if (res == 1) {
|
|
Packit |
db01ca |
strcpy(input_buf, complition_struct.items[0]);
|
|
Packit |
db01ca |
strcat(input_buf, " ");
|
|
Packit |
db01ca |
ind = print_str_by_index(input_buf, ind, -1);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
memset(input_buf, 0, READ_BUF_SIZE);
|
|
Packit |
db01ca |
strncpy(input_buf, complition_struct.items[0],
|
|
Packit |
db01ca |
complition_struct.comp_len);
|
|
Packit |
db01ca |
ind = print_str_by_index(input_buf, ind, -1);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case NL_KEY:
|
|
Packit |
db01ca |
printf("%c", c);
|
|
Packit |
db01ca |
if (current_hist_ind != hist_ind)
|
|
Packit |
db01ca |
add_to_history(input_buf, hist_ind);
|
|
Packit |
db01ca |
if (strlen(input_buf) == 0) return("");
|
|
Packit |
db01ca |
add_to_history(input_buf, current_hist_ind);
|
|
Packit |
db01ca |
return(History[current_hist_ind]);
|
|
Packit |
db01ca |
case CTRL_K_KEY:
|
|
Packit |
db01ca |
clear_line(ind, len);
|
|
Packit |
db01ca |
memset(input_buf + ind, 0, len - ind);
|
|
Packit |
db01ca |
print_str_by_index(input_buf, 0, ind);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case CTRL_N_KEY:
|
|
Packit |
db01ca |
ungetc(DOWN_KEY, stdin);
|
|
Packit |
db01ca |
ungetc(CTRL2_KEY, stdin);
|
|
Packit |
db01ca |
ungetc(CTRL1_KEY, stdin);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case CTRL_R_KEY:
|
|
Packit |
db01ca |
case CTRL_S_KEY:
|
|
Packit |
db01ca |
res = find_command(input_buf, hist_ind,
|
|
Packit |
db01ca |
(c == CTRL_S_KEY));
|
|
Packit |
db01ca |
if (res != hist_ind) {
|
|
Packit |
db01ca |
hist_ind = res;
|
|
Packit |
db01ca |
memset(input_buf, 0, READ_BUF_SIZE);
|
|
Packit |
db01ca |
strcpy(input_buf, History[hist_ind]);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
print_str_by_index(Title, 0, -1);
|
|
Packit |
db01ca |
ind = print_str_by_index(input_buf, 0, -1);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case CTRL1_KEY:
|
|
Packit |
db01ca |
c = getchar();
|
|
Packit |
db01ca |
if (c != CTRL2_KEY) break;
|
|
Packit |
db01ca |
c = getchar();
|
|
Packit |
db01ca |
switch (c) {
|
|
Packit |
db01ca |
case INSERT_KEY:
|
|
Packit |
db01ca |
getchar();
|
|
Packit |
db01ca |
is_insert_key = (is_insert_key) ? 0 : 1;
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case DELETE_KEY:
|
|
Packit |
db01ca |
getchar();
|
|
Packit |
db01ca |
if (ind == len) break;
|
|
Packit |
db01ca |
ind = delete_char(input_buf, len, ind, 1);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case LEFT_KEY:
|
|
Packit |
db01ca |
printf("%c", '\b');
|
|
Packit |
db01ca |
ind--;
|
|
Packit |
db01ca |
if (ind < 0) {
|
|
Packit |
db01ca |
ind = 0;
|
|
Packit |
db01ca |
printf("%c", ' ');
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case RIGHT_KEY:
|
|
Packit |
db01ca |
ind++;
|
|
Packit |
db01ca |
if (ind > len) ind = len;
|
|
Packit |
db01ca |
else print_str_by_index(input_buf, ind - 1, ind);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case UP_KEY:
|
|
Packit |
db01ca |
case DOWN_KEY:
|
|
Packit |
db01ca |
clear_line(ind, len);
|
|
Packit |
db01ca |
if (c == UP_KEY)
|
|
Packit |
db01ca |
str = get_history_prev(input_buf);
|
|
Packit |
db01ca |
else
|
|
Packit |
db01ca |
str = get_history_next(input_buf);
|
|
Packit |
db01ca |
memset(input_buf, 0, READ_BUF_SIZE);
|
|
Packit |
db01ca |
strcpy(input_buf, str);
|
|
Packit |
db01ca |
len = strlen(input_buf);
|
|
Packit |
db01ca |
ind = print_str_by_index(input_buf, 0, len);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case PGUP_KEY:
|
|
Packit |
db01ca |
case PGDOWN_KEY:
|
|
Packit |
db01ca |
getchar();
|
|
Packit |
db01ca |
add_to_history(input_buf, hist_ind);
|
|
Packit |
db01ca |
clear_line(ind, len);
|
|
Packit |
db01ca |
hist_ind = (c == PGUP_KEY) ? 0 : current_hist_ind;
|
|
Packit |
db01ca |
str = History[hist_ind];
|
|
Packit |
db01ca |
memset(input_buf, 0, READ_BUF_SIZE);
|
|
Packit |
db01ca |
strcpy(input_buf, str);
|
|
Packit |
db01ca |
len = strlen(input_buf);
|
|
Packit |
db01ca |
ind = print_str_by_index(input_buf, 0, len);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case HOME_KEY:
|
|
Packit |
db01ca |
go_to_begin(ind);
|
|
Packit |
db01ca |
ind = print_str_by_index(input_buf, 0, 0);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case END_KEY:
|
|
Packit |
db01ca |
ind = print_str_by_index(input_buf, ind, len);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
case CTRL_H_KEY:
|
|
Packit |
db01ca |
case BACKSP_KEY:
|
|
Packit |
db01ca |
ind = (ind <= 0) ? 0 : delete_char(input_buf, len, ind, 0);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
default:
|
|
Packit |
db01ca |
if (ind == len) {
|
|
Packit |
db01ca |
input_buf[ind++] = c;
|
|
Packit |
db01ca |
printf("%c", c);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
ind = add_char(input_buf, len, c, ind);
|
|
Packit |
db01ca |
break;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
if (ind >= (READ_BUF_SIZE - 1)) {
|
|
Packit |
db01ca |
if (current_hist_ind != hist_ind)
|
|
Packit |
db01ca |
add_to_history(input_buf, hist_ind);
|
|
Packit |
db01ca |
add_to_history(input_buf, current_hist_ind);
|
|
Packit |
db01ca |
return(History[current_hist_ind]);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
return((char *)NULL);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
void set_current_history(char *line)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
if (line == (char *)NULL) return;
|
|
Packit |
db01ca |
if (strlen(line) == 0) return;
|
|
Packit |
db01ca |
if (strcmp(History[current_hist_ind], line) == 0) return;
|
|
Packit |
db01ca |
free(History[current_hist_ind]);
|
|
Packit |
db01ca |
History[current_hist_ind] = strdup(line);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
char *get_last_history(void)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
if (current_hist_ind > 0)
|
|
Packit |
db01ca |
return(History[current_hist_ind - 1]);
|
|
Packit |
db01ca |
return((char *)NULL);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
char *get_def_history(char *text, int *count)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
int ind, i, res;
|
|
Packit |
db01ca |
char *tmp, c;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
tmp = text;
|
|
Packit |
db01ca |
i = *count;
|
|
Packit |
db01ca |
while((*tmp != ' ') && (*tmp != 0)) {
|
|
Packit |
db01ca |
tmp++;
|
|
Packit |
db01ca |
i++;
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
c = *tmp;
|
|
Packit |
db01ca |
*tmp = 0;
|
|
Packit |
db01ca |
if (isdigit(*text)) {
|
|
Packit |
db01ca |
ind = atoi(text);
|
|
Packit |
db01ca |
*tmp = c;
|
|
Packit |
db01ca |
if ((ind < 0) || (ind > current_hist_ind))
|
|
Packit |
db01ca |
return((char *)NULL);
|
|
Packit |
db01ca |
*count = i;
|
|
Packit |
db01ca |
return(History[ind]);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
res = find_cmd_by_text(text, current_hist_ind - 1, 0);
|
|
Packit |
db01ca |
*tmp = c;
|
|
Packit |
db01ca |
if (res == -1) return((char *)NULL);
|
|
Packit |
db01ca |
*count = i;
|
|
Packit |
db01ca |
return(History[res]);
|
|
Packit |
db01ca |
}
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
ret_code_t history_cmd(void)
|
|
Packit |
db01ca |
{
|
|
Packit |
db01ca |
int i;
|
|
Packit |
db01ca |
|
|
Packit |
db01ca |
for (i = 0; i <= current_hist_ind; i++) {
|
|
Packit |
db01ca |
printf("[ %d ] %s\n", i, History[i]);
|
|
Packit |
db01ca |
};
|
|
Packit |
db01ca |
return(HPI_SHELL_OK);
|
|
Packit |
db01ca |
}
|