tg/interface.c

156 lines
2.8 KiB
C
Raw Normal View History

2013-10-03 08:38:25 -04:00
#define _GNU_SOURCE
#include <readline/readline.h>
#include <readline/history.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include.h"
char *default_prompt = ">";
char *get_default_prompt (void) {
return default_prompt;
}
char *complete_none (const char *text UU, int state UU) {
return 0;
}
char *commands[] = {
"help",
"msg",
0 };
int commands_flags[] = {
070,
072,
};
2013-10-03 12:09:06 -04:00
2013-10-03 08:38:25 -04:00
char *a = 0;
char **user_list = &a;
char **chat_list = &a;
int init_token (char **q) {
char *r = *q;
while (*r == ' ') { r ++; }
if (!*r) { return 0; }
2013-10-03 12:09:06 -04:00
*q = r;
2013-10-03 08:38:25 -04:00
return 1;
}
char *get_token (char **q, int *l) {
char *r = *q;
while (*r == ' ') { r ++; }
if (!*r) {
2013-10-03 12:09:06 -04:00
*q = r;
2013-10-03 08:38:25 -04:00
*l = 0;
return 0;
}
int neg = 0;
char *s = r;
while (*r && (*r != ' ' || neg)) {
if (*r == '\\') {
neg = 1 - neg;
} else {
neg = 0;
}
2013-10-03 12:09:06 -04:00
r++;
2013-10-03 08:38:25 -04:00
}
2013-10-03 12:09:06 -04:00
*q = r;
2013-10-03 08:38:25 -04:00
*l = r - s;
return s;
}
int get_complete_mode (void) {
char *q = rl_line_buffer;
if (!init_token (&q)) { return 0; }
int l = 0;
char *r = get_token (&q, &l);
if (!*q) { return 0; }
char **command = commands;
int n = 0;
int flags = -1;
while (*command) {
2013-10-03 12:09:06 -04:00
if (!strncmp (r, *command, l)) {
2013-10-03 08:38:25 -04:00
flags = commands_flags[n];
break;
}
n ++;
command ++;
}
if (flags == -1) {
return -1;
}
int s = 0;
while (1) {
get_token (&q, &l);
if (!*q) { return flags & 7; }
s ++;
if (s <= 4) { flags >>= 3; }
}
}
int complete_string_list (char **list, int index, const char *text, int len, char **R) {
index ++;
2013-10-03 12:09:06 -04:00
while (list[index] && strncmp (list[index], text, len)) {
2013-10-03 08:38:25 -04:00
index ++;
}
2013-10-03 12:09:06 -04:00
if (list[index]) {
2013-10-03 08:38:25 -04:00
*R = strdup (list[index]);
return index;
} else {
*R = 0;
return -1;
}
}
char *command_generator (const char *text, int state) {
static int len, index, mode;
2013-10-03 12:09:06 -04:00
2013-10-03 08:38:25 -04:00
if (!state) {
len = strlen (text);
index = -1;
rl_line_buffer[rl_point] = '\0'; /* the effect should be such
2013-10-03 12:10:53 -04:00
* that the cursor position
* is at the end of line for
* the auto completion regex
* above (note the $ at end)
*/
2013-10-03 08:38:25 -04:00
mode = get_complete_mode ();
} else {
if (index == -1) { return 0; }
}
if (mode == -1) { return 0; }
char *R = 0;
switch (mode & 7) {
case 0:
index = complete_string_list (commands, index, text, len, &R);
return R;
case 1:
index = complete_string_list (user_list, index, text, len, &R);
return R;
case 2:
index = complete_string_list (chat_list, index, text, len, &R);
return R;
case 3:
return rl_filename_completion_function(text,state);
default:
return 0;
}
}
char **complete_text (char *text, int start UU, int end UU) {
return (char **) rl_completion_matches (text, command_generator);
}
void interpreter (char *line UU) {
assert (0);
}