* More R_API-zation
* More stuff in doc/release
* Added 'dk' for sending signals to processes in the debugger
- A bit hacky, but funny enought for testing
* Initial draft of the process-related API
- For handling tree's of processes with threads
* Fix a bug in dietline ('supr' key is working now
This commit is contained in:
parent
936db0db87
commit
70186e1120
13 changed files with 200 additions and 81 deletions
3
TODO
3
TODO
|
|
@ -2,12 +2,15 @@
|
|||
* Add maxrows option for r_print (fix visual problem)
|
||||
* Drop #if conditionals to use #ifdef ones
|
||||
- fits better with plan9 compiler
|
||||
- use getopt() p9-like macros
|
||||
|
||||
* Add test for config.c with _set_cb
|
||||
* Rename __UNIX__ as __POSIX__
|
||||
* Strip non input symbols in plugins (speed up loading)
|
||||
* Specify binmask in hexpairs
|
||||
- wx 1234:ff0f
|
||||
- /x 1234:ff0f
|
||||
|
||||
* radare2 -e dbg.engine=vm -d ls
|
||||
- resolve path for ls
|
||||
- load the program using r_bin in virtual space
|
||||
|
|
|
|||
17
doc/releases
17
doc/releases
|
|
@ -5,9 +5,10 @@ The objective of this paper is to determine a set of rules to be done before
|
|||
each release and define the instructions for generating the distribution
|
||||
tarball together with a scheduler.
|
||||
|
||||
|
||||
* We try to release every 1/2 months
|
||||
* Version numbering (actually we dont follow any rules for this)
|
||||
* Codenames for releases MUST be funny (until we didnt get a name that can make
|
||||
me laught, we should not release anything!)
|
||||
|
||||
Before any release we have to:
|
||||
|
||||
|
|
@ -28,3 +29,17 @@ Before any release we have to:
|
|||
If available, it would be good to have some unit tests to check nothing is
|
||||
broken. Maybe Vala is the way to go when writing tests, because this way
|
||||
we ensure that pkg-config, libr and vapis works in a shot.
|
||||
|
||||
- Test build on different platforms
|
||||
|
||||
The same codebase should be compilable on *nix and w32 systems without
|
||||
modifications. It should be also possible to build it with make threads,
|
||||
so using quadcore boxes with -j8 should be a good place for finding
|
||||
race conditions in the build system.
|
||||
|
||||
- Remove commented code and review TODO/BUG/XXX comments
|
||||
|
||||
While developing a new release, it's pretty common to keep old versions of
|
||||
the code for testing parts of libraries and be able to go back or find bugs
|
||||
while refactoring code or re-doing-it from scratch. This code, should be
|
||||
reviewed and removed if necessary.
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@ DEPS=r_config r_cons r_line r_io r_cmd r_util r_print r_flags r_asm r_lib r_macr
|
|||
OBJ=core.o cmd.o file.o config.o visual.o io.o yank.o libs.o
|
||||
|
||||
CFLAGS+=-DLIBDIR=\"${PREFIX}/lib\"
|
||||
CFLAGS+=-DPREFIX=\"${PREFIX}\"
|
||||
|
||||
include ../rules.mk
|
||||
|
|
|
|||
|
|
@ -469,8 +469,6 @@ static int cmd_flag(void *data, const char *input)
|
|||
break;
|
||||
case 'o':
|
||||
{
|
||||
// XXX
|
||||
#define PREFIX "/usr"
|
||||
char *file = PREFIX"/share/doc/radare/fortunes";
|
||||
char *line = r_file_slurp_random_line (file);
|
||||
r_cons_printf("%s\n", line);
|
||||
|
|
@ -1376,7 +1374,23 @@ int r_core_cmd_file(struct r_core_t *core, const char *file)
|
|||
static int cmd_debug(void *data, const char *input)
|
||||
{
|
||||
struct r_core_t *core = (struct r_core_t *)data;
|
||||
char *ptr;
|
||||
switch(input[0]) {
|
||||
case 'k':
|
||||
{
|
||||
/* XXX: not for threads? signal is for a whole process!! */
|
||||
/* XXX: but we want fine-grained access to process resources */
|
||||
int pid = 0;
|
||||
int sig = 9;
|
||||
pid = atoi(input);
|
||||
ptr = strchr(input, ' ');
|
||||
if (ptr) sig = atoi(ptr+1);
|
||||
if (pid > 0) {
|
||||
fprintf(stderr, "Sending signal '%d' to pid '%d'\n");
|
||||
r_debug_kill(&core->dbg, pid, sig);
|
||||
} else fprintf(stderr, "Invalid arguments\n");
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
fprintf(stderr, "step\n");
|
||||
r_debug_step(&core->dbg, 1);
|
||||
|
|
@ -1415,6 +1429,7 @@ static int cmd_debug(void *data, const char *input)
|
|||
" ds 3 ; perform 3 steps\n"
|
||||
" do 3 ; perform 3 steps overs\n"
|
||||
" dp [pid] ; list or set pid\n"
|
||||
" dt [tid] ; select thread id\n"
|
||||
" dc ; continue execution\n"
|
||||
" dr ; show registers\n"
|
||||
" dr* ; show registers in radare commands\n"
|
||||
|
|
@ -1425,7 +1440,8 @@ static int cmd_debug(void *data, const char *input)
|
|||
" db -sym.main ; drop breakpoint\n"
|
||||
" dm ; show memory maps\n"
|
||||
" dm 4096 ; allocate 4KB in child process\n"
|
||||
" dm rw- esp 9K; set 9KB of the stack as read+write (no exec)\n");
|
||||
" dm rw- esp 9K; set 9KB of the stack as read+write (no exec)\n"
|
||||
" dk pid sig ; send signal to a process ID\n");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
#include <r_core.h>
|
||||
|
||||
u64 r_core_file_resize(struct r_core_t *core, u64 newsize)
|
||||
R_API u64 r_core_file_resize(struct r_core_t *core, u64 newsize)
|
||||
{
|
||||
if (newsize == 0 && core->file)
|
||||
return core->file->size;
|
||||
return 0LL;
|
||||
}
|
||||
|
||||
struct r_core_file_t *r_core_file_open(struct r_core_t *r, const char *file, int mode)
|
||||
R_API struct r_core_file_t *r_core_file_open(struct r_core_t *r, const char *file, int mode)
|
||||
{
|
||||
struct r_core_file_t *fh;
|
||||
int fd;
|
||||
|
|
@ -40,20 +40,20 @@ struct r_core_file_t *r_core_file_open(struct r_core_t *r, const char *file, int
|
|||
return fh;
|
||||
}
|
||||
|
||||
int r_core_file_set(struct r_core_t *r, struct r_core_file_t *fh)
|
||||
R_API int r_core_file_set(struct r_core_t *r, struct r_core_file_t *fh)
|
||||
{
|
||||
r->file = fh;
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
int r_core_file_close(struct r_core_t *r, struct r_core_file_t *fh)
|
||||
R_API int r_core_file_close(struct r_core_t *r, struct r_core_file_t *fh)
|
||||
{
|
||||
int ret = r_io_close(&r->io, fh->fd);
|
||||
list_del(&(fh->list));
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct r_core_file_t *r_core_file_get_fd(struct r_core_t *core, int fd)
|
||||
R_API struct r_core_file_t *r_core_file_get_fd(struct r_core_t *core, int fd)
|
||||
{
|
||||
struct list_head *pos;
|
||||
list_for_each_prev(pos, &core->files) {
|
||||
|
|
@ -64,7 +64,7 @@ struct r_core_file_t *r_core_file_get_fd(struct r_core_t *core, int fd)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int r_core_file_close_fd(struct r_core_t *core, int fd)
|
||||
R_API int r_core_file_close_fd(struct r_core_t *core, int fd)
|
||||
{
|
||||
int ret = r_io_close(&core->io, fd);
|
||||
struct r_core_file_t *fh = r_core_file_get_fd(core, fd);
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ R_API int r_core_loadlibs_init(struct r_core_t *core)
|
|||
|
||||
R_API int r_core_loadlibs(struct r_core_t *core)
|
||||
{
|
||||
/* TODO: all those default plugin paths should be defined in r_lib */
|
||||
char *homeplugindir = r_str_home(".radare/plugins");
|
||||
static int singleton = R_TRUE;
|
||||
if (singleton) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
NAME=r_debug
|
||||
OBJ=debug.o handle.o
|
||||
OBJ=debug.o handle.o pid.o
|
||||
|
||||
include ../rules.mk
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <r_debug.h>
|
||||
|
||||
int r_debug_init(struct r_debug_t *dbg)
|
||||
R_API int r_debug_init(struct r_debug_t *dbg)
|
||||
{
|
||||
dbg->pid = -1;
|
||||
dbg->tid = -1;
|
||||
|
|
@ -12,7 +12,7 @@ int r_debug_init(struct r_debug_t *dbg)
|
|||
return R_TRUE;
|
||||
}
|
||||
|
||||
struct r_debug_t *r_debug_new()
|
||||
R_API struct r_debug_t *r_debug_new()
|
||||
{
|
||||
struct r_debug_t *dbg;
|
||||
dbg = MALLOC_STRUCT(struct r_debug_t);
|
||||
|
|
@ -20,7 +20,7 @@ struct r_debug_t *r_debug_new()
|
|||
return dbg;
|
||||
}
|
||||
|
||||
int r_debug_attach(struct r_debug_t *dbg, int pid)
|
||||
R_API int r_debug_attach(struct r_debug_t *dbg, int pid)
|
||||
{
|
||||
int ret = R_FALSE;
|
||||
if (dbg->h && dbg->h->attach) {
|
||||
|
|
@ -33,24 +33,24 @@ int r_debug_attach(struct r_debug_t *dbg, int pid)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int r_debug_startv(struct r_debug_t *dbg, int argc, char **argv)
|
||||
R_API int r_debug_startv(struct r_debug_t *dbg, int argc, char **argv)
|
||||
{
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
int r_debug_start(struct r_debug_t *dbg, const char *cmd)
|
||||
R_API int r_debug_start(struct r_debug_t *dbg, const char *cmd)
|
||||
{
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
int r_debug_detach(struct r_debug_t *dbg, int pid)
|
||||
R_API int r_debug_detach(struct r_debug_t *dbg, int pid)
|
||||
{
|
||||
if (dbg->h && dbg->h->detach)
|
||||
return dbg->h->detach(pid);
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
int r_debug_select(struct r_debug_t *dbg, int pid, int tid)
|
||||
R_API int r_debug_select(struct r_debug_t *dbg, int pid, int tid)
|
||||
{
|
||||
dbg->pid = pid;
|
||||
dbg->tid = tid;
|
||||
|
|
@ -58,7 +58,7 @@ int r_debug_select(struct r_debug_t *dbg, int pid, int tid)
|
|||
return R_TRUE;
|
||||
}
|
||||
|
||||
int r_debug_set_arch(struct r_debug_t *dbg, int arch)
|
||||
R_API int r_debug_set_arch(struct r_debug_t *dbg, int arch)
|
||||
{
|
||||
switch(arch) {
|
||||
case R_DBG_ARCH_BF:
|
||||
|
|
@ -72,7 +72,7 @@ int r_debug_set_arch(struct r_debug_t *dbg, int arch)
|
|||
}
|
||||
|
||||
/*--*/
|
||||
int r_debug_stop_reason(struct r_debug_t *dbg)
|
||||
R_API int r_debug_stop_reason(struct r_debug_t *dbg)
|
||||
{
|
||||
// TODO: return reason to stop debugging
|
||||
// - new process
|
||||
|
|
@ -83,7 +83,7 @@ int r_debug_stop_reason(struct r_debug_t *dbg)
|
|||
return R_TRUE;
|
||||
}
|
||||
|
||||
int r_debug_wait(struct r_debug_t *dbg)
|
||||
R_API int r_debug_wait(struct r_debug_t *dbg)
|
||||
{
|
||||
int ret = R_FALSE;
|
||||
if (dbg->h->wait)
|
||||
|
|
@ -92,7 +92,7 @@ int r_debug_wait(struct r_debug_t *dbg)
|
|||
}
|
||||
|
||||
// TODO: count number of steps done to check if no error??
|
||||
int r_debug_step(struct r_debug_t *dbg, int steps)
|
||||
R_API int r_debug_step(struct r_debug_t *dbg, int steps)
|
||||
{
|
||||
int i, ret = R_FALSE;
|
||||
if (dbg->h && dbg->h->step) {
|
||||
|
|
@ -109,20 +109,20 @@ int r_debug_step(struct r_debug_t *dbg, int steps)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int r_debug_syscall(struct r_debug_t *dbg, int num)
|
||||
R_API int r_debug_syscall(struct r_debug_t *dbg, int num)
|
||||
{
|
||||
fprintf(stderr, "TODO\n");
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
int r_debug_step_over(struct r_debug_t *dbg, int steps)
|
||||
R_API int r_debug_step_over(struct r_debug_t *dbg, int steps)
|
||||
{
|
||||
// TODO: analyze opcode if it is stepoverable
|
||||
fprintf(stderr, "TODO\n");
|
||||
return r_debug_step(dbg, steps);
|
||||
}
|
||||
|
||||
int r_debug_continue(struct r_debug_t *dbg)
|
||||
R_API int r_debug_continue(struct r_debug_t *dbg)
|
||||
{
|
||||
int ret = R_FALSE;
|
||||
if (dbg->h){
|
||||
|
|
@ -135,12 +135,12 @@ int r_debug_continue(struct r_debug_t *dbg)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int r_debug_continue_until(struct r_debug_t *dbg, u64 addr)
|
||||
R_API int r_debug_continue_until(struct r_debug_t *dbg, u64 addr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int r_debug_continue_syscall(struct r_debug_t *dbg, int sc)
|
||||
R_API int r_debug_continue_syscall(struct r_debug_t *dbg, int sc)
|
||||
{
|
||||
int ret = R_FALSE;
|
||||
if (dbg->h && dbg->h->contsc)
|
||||
|
|
@ -149,7 +149,7 @@ int r_debug_continue_syscall(struct r_debug_t *dbg, int sc)
|
|||
}
|
||||
|
||||
// XXX wrong function name
|
||||
int r_debug_use_software_steps(struct r_debug_t *dbg, int value)
|
||||
R_API int r_debug_use_software_steps(struct r_debug_t *dbg, int value)
|
||||
{
|
||||
/* use software breakpoints and continues */
|
||||
return -1;
|
||||
|
|
@ -157,18 +157,18 @@ int r_debug_use_software_steps(struct r_debug_t *dbg, int value)
|
|||
|
||||
/* registers */
|
||||
|
||||
int r_debug_register_get(struct r_debug_t *dbg, int reg, u64 *value)
|
||||
R_API int r_debug_register_get(struct r_debug_t *dbg, int reg, u64 *value)
|
||||
{
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
int r_debug_register_set(struct r_debug_t *dbg, int reg, u64 value)
|
||||
R_API int r_debug_register_set(struct r_debug_t *dbg, int reg, u64 value)
|
||||
{
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
/* for debugging purposes? */
|
||||
int r_debug_register_list(struct r_debug_t *dbg)
|
||||
R_API int r_debug_register_list(struct r_debug_t *dbg)
|
||||
{
|
||||
int i =0;
|
||||
for(i=0;i<dbg->reg.nregs;i++) {
|
||||
|
|
@ -179,14 +179,26 @@ int r_debug_register_list(struct r_debug_t *dbg)
|
|||
return R_TRUE;
|
||||
}
|
||||
|
||||
// TODO: Move to pid.c ?
|
||||
// TODO: Do we need an intermediate signal representation for portability?
|
||||
// TODO: STOP, CONTINUE, KILL, ...
|
||||
R_API int r_debug_kill(struct r_debug_t *dbg, int pid, int sig)
|
||||
{
|
||||
// XXX: use debugger handler backend here
|
||||
#include <signal.h>
|
||||
int ret = kill(pid, sig);
|
||||
if (ret == -1)
|
||||
return R_FALSE;
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
/* mmu */
|
||||
|
||||
int r_debug_mmu_alloc(struct r_debug_t *dbg, u64 size, u64 *addr)
|
||||
R_API int r_debug_mmu_alloc(struct r_debug_t *dbg, u64 size, u64 *addr)
|
||||
{
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
int r_debug_mmu_free(struct r_debug_t *dbg, u64 addr)
|
||||
R_API int r_debug_mmu_free(struct r_debug_t *dbg, u64 addr)
|
||||
{
|
||||
return R_TRUE;
|
||||
}
|
||||
|
|
|
|||
43
libr/debug/pid.c
Normal file
43
libr/debug/pid.c
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* radare - LGPL - Copyright 2009 pancake<nopcode.org> */
|
||||
|
||||
#include <r_debug.h>
|
||||
|
||||
R_API int r_debug_pid_list(struct r_debug_t *dbg)
|
||||
{
|
||||
int count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* processes */
|
||||
R_API int r_debug_pid_add(struct r_debug_t *dbg)
|
||||
{
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_debug_pid_del(struct r_debug_t *dbg)
|
||||
{
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
/* threads */
|
||||
R_API int r_debug_pid_add_thread(struct r_debug_t *dbg)
|
||||
{
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API int r_debug_pid_del_thread(struct r_debug_t *dbg)
|
||||
{
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
/* status */
|
||||
R_API int r_debug_pid_set_status(struct r_debug_t *dbg, int pid, int status)
|
||||
{
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
/* status */
|
||||
R_API struct r_debug_pid_t *r_debug_pid_get(struct r_debug_t *dbg, int pid)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <r_flags.h>
|
||||
|
||||
const const char *r_flag_space_get(struct r_flag_t *f, int idx)
|
||||
R_API const char *r_flag_space_get(struct r_flag_t *f, int idx)
|
||||
{
|
||||
if (idx==-1)
|
||||
return "";
|
||||
|
|
@ -24,7 +24,7 @@ void flag_space_init(struct r_flag_t *f)
|
|||
}
|
||||
#endif
|
||||
|
||||
void r_flag_space_set(struct r_flag_t *f, const char *name)
|
||||
R_API void r_flag_space_set(struct r_flag_t *f, const char *name)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<R_FLAG_SPACES_MAX;i++) {
|
||||
|
|
@ -44,7 +44,7 @@ void r_flag_space_set(struct r_flag_t *f, const char *name)
|
|||
}
|
||||
}
|
||||
|
||||
void r_flag_space_list(struct r_flag_t *f)
|
||||
R_API void r_flag_space_list(struct r_flag_t *f)
|
||||
{
|
||||
int i,j = 0;
|
||||
for(i=0;i<R_FLAG_SPACES_MAX;i++) {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,28 @@ struct r_debug_t {
|
|||
int (*write)(int pid, u64 addr, u8 *buf, int len);
|
||||
struct r_debug_handle_t *h;
|
||||
struct list_head handlers;
|
||||
/* TODO
|
||||
- list of processes and their threads
|
||||
- list of mapped memory (from /proc/XX/maps)
|
||||
- list of managed memory (allocated in child...)
|
||||
*/
|
||||
};
|
||||
|
||||
enum {
|
||||
R_DBG_PROC_STOP,
|
||||
R_DBG_PROC_RUN,
|
||||
R_DBG_PROC_SLEEP,
|
||||
R_DBG_PROC_ZOMBIE,
|
||||
};
|
||||
|
||||
struct r_debug_pid_t {
|
||||
int pid;
|
||||
int status; /* stopped, running, zombie, sleeping ,... */
|
||||
int runnable; /* when using 'run', 'continue', .. this proc will be runnable */
|
||||
struct list_head threads;
|
||||
struct list_head childs;
|
||||
struct r_debug_pid_t *parent;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
int r_debug_handle_add(struct r_debug_t *dbg, struct r_debug_handle_t *foo);
|
||||
|
|
@ -52,6 +74,8 @@ int r_debug_handle_set(struct r_debug_t *dbg, const char *str);
|
|||
int r_debug_handle_init(struct r_debug_t *dbg);
|
||||
int r_debug_init(struct r_debug_t *dbg);
|
||||
|
||||
/* send signals */
|
||||
int r_debug_kill(struct r_debug_t *dbg, int pid, int sig);
|
||||
int r_debug_step(struct r_debug_t *dbg, int steps);
|
||||
int r_debug_continue(struct r_debug_t *dbg);
|
||||
int r_debug_select(struct r_debug_t *dbg, int pid, int tid);
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ extern int r_line_disable;
|
|||
int r_line_init();
|
||||
int r_line_hist_load(const char *file);
|
||||
char *r_line_readline(int argc, const char **argv);
|
||||
extern int r_line_readchar();
|
||||
extern int r_line_hist_add(const char *line);
|
||||
//extern int r_line_readchar();
|
||||
R_API int r_line_hist_add(const char *line);
|
||||
int r_line_hist_save(const char *file);
|
||||
int r_line_hist_label(const char *label, void (*cb)(const char*));
|
||||
void r_line_label_show();
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ int r_line_disable = 0; // TODO use fgets..no autocompletion
|
|||
// char **rad_autocompletion(const char *text, int start, int end)
|
||||
// return matches = rl_completion_matches (text, rad_offset_matches);
|
||||
|
||||
int r_line_readchar()
|
||||
static int r_line_readchar()
|
||||
{
|
||||
char buf[2];
|
||||
#if __WINDOWS__
|
||||
|
|
@ -53,9 +53,8 @@ int r_line_readchar()
|
|||
ret = ReadConsole(h, buf,1, &out, NULL);
|
||||
if (!ret) {
|
||||
// wine hack-around
|
||||
if (read(0,buf,1) == 1)
|
||||
return buf[0];
|
||||
return -1;
|
||||
if (read(0,buf,1) != 1)
|
||||
return -1
|
||||
}
|
||||
SetConsoleMode(h, mode);
|
||||
#else
|
||||
|
|
@ -63,11 +62,13 @@ int r_line_readchar()
|
|||
if (ret <1)
|
||||
return -1;
|
||||
#endif
|
||||
//printf("CHAR(%d)\n", buf[0]);
|
||||
return buf[0];
|
||||
}
|
||||
|
||||
/* scripting */
|
||||
|
||||
/* TODO: remove label related stuff */
|
||||
#if 0
|
||||
#define BLOCK 4096
|
||||
static char *labels = NULL;
|
||||
|
|
@ -170,7 +171,7 @@ int r_line_hist_label(const char *label, void (*cb)(const char*))
|
|||
return 1;
|
||||
}
|
||||
|
||||
int r_line_hist_add(const char *line)
|
||||
R_API int r_line_hist_add(const char *line)
|
||||
{
|
||||
#if HAVE_LIB_READLINE
|
||||
add_history(line);
|
||||
|
|
@ -185,7 +186,7 @@ int r_line_hist_add(const char *line)
|
|||
//#endif
|
||||
}
|
||||
|
||||
int r_line_hist_up()
|
||||
static int r_line_hist_up()
|
||||
{
|
||||
if (r_line_histidx>0) {
|
||||
strncpy(r_line_buffer, r_line_history[--r_line_histidx], R_LINE_BUFSIZE-1);
|
||||
|
|
@ -196,7 +197,7 @@ int r_line_hist_up()
|
|||
return 0;
|
||||
}
|
||||
|
||||
int r_line_hist_down()
|
||||
static int r_line_hist_down()
|
||||
{
|
||||
r_line_buffer_idx=0;
|
||||
if (r_line_histidx<r_line_histsize) {
|
||||
|
|
@ -213,7 +214,7 @@ int r_line_hist_down()
|
|||
return 0;
|
||||
}
|
||||
|
||||
int r_line_hist_list()
|
||||
R_API int r_line_hist_list()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
|
@ -227,7 +228,7 @@ int r_line_hist_list()
|
|||
return i;
|
||||
}
|
||||
|
||||
int r_line_hist_free()
|
||||
R_API int r_line_hist_free()
|
||||
{
|
||||
int i;
|
||||
if (r_line_history != NULL)
|
||||
|
|
@ -238,7 +239,8 @@ int r_line_hist_free()
|
|||
return r_line_histidx=0, r_line_histsize;
|
||||
}
|
||||
|
||||
void r_line_free()
|
||||
/* TODO: we need an state..? */
|
||||
R_API void r_line_free()
|
||||
{
|
||||
printf("Bye!\n");
|
||||
r_line_hist_free();
|
||||
|
|
@ -247,7 +249,7 @@ void r_line_free()
|
|||
}
|
||||
|
||||
/* load history from file. if file == NULL load from ~/.<prg>.history or so */
|
||||
int r_line_hist_load(const char *file)
|
||||
R_API int r_line_hist_load(const char *file)
|
||||
{
|
||||
#if HAVE_LIB_READLINE
|
||||
rad_readline_init();
|
||||
|
|
@ -273,7 +275,7 @@ int r_line_hist_load(const char *file)
|
|||
#endif
|
||||
}
|
||||
|
||||
int r_line_hist_save(const char *file)
|
||||
R_API int r_line_hist_save(const char *file)
|
||||
{
|
||||
#if HAVE_LIB_READLINE
|
||||
rad_readline_finish();
|
||||
|
|
@ -296,14 +298,14 @@ int r_line_hist_save(const char *file)
|
|||
#endif
|
||||
}
|
||||
|
||||
int r_line_hist_chop(const char *file, int limit)
|
||||
R_API int r_line_hist_chop(const char *file, int limit)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initialize history stuff */
|
||||
int r_line_init()
|
||||
R_API int r_line_init()
|
||||
{
|
||||
#if HAVE_LIB_READLINE
|
||||
rad_readline_init();
|
||||
|
|
@ -324,8 +326,8 @@ int r_line_init()
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* test */
|
||||
int r_line_printchar()
|
||||
/* TODO: Remove this test case .. this is not R_API */
|
||||
static int r_line_printchar()
|
||||
{
|
||||
unsigned char buf[10];
|
||||
|
||||
|
|
@ -333,30 +335,30 @@ int r_line_printchar()
|
|||
buf[0]=r_line_readchar();
|
||||
|
||||
switch(buf[0]) {
|
||||
case 226:
|
||||
case 197:
|
||||
case 195:
|
||||
case 194:
|
||||
buf[0] = r_line_readchar();
|
||||
printf("unicode-%02x-%02x\n", buf[0],buf[1]);
|
||||
break;
|
||||
case 8: // wtf is 127?
|
||||
case 127: printf("backspace\n"); break;
|
||||
case 32: printf("space\n"); break;
|
||||
case 27:
|
||||
read(0, buf, 5);
|
||||
printf("esc-%02x-%02x-%02x-%02x\n",
|
||||
buf[0],buf[1],buf[2],buf[3]);
|
||||
break;
|
||||
case 12: printf("^L\n"); break;
|
||||
case 13: printf("intro\n"); break;
|
||||
case 18: printf("^R\n"); break;
|
||||
case 9: printf("tab\n"); break;
|
||||
case 3: printf("control-c\n"); break;
|
||||
case 0: printf("control-space\n"); break;
|
||||
default:
|
||||
printf("(code:%d)\n", buf[0]);
|
||||
break;
|
||||
case 226:
|
||||
case 197:
|
||||
case 195:
|
||||
case 194:
|
||||
buf[0] = r_line_readchar();
|
||||
printf("unicode-%02x-%02x\n", buf[0],buf[1]);
|
||||
break;
|
||||
case 8: // wtf is 127?
|
||||
case 127: printf("backspace\n"); break;
|
||||
case 32: printf("space\n"); break;
|
||||
case 27:
|
||||
read(0, buf, 5);
|
||||
printf("esc-%02x-%02x-%02x-%02x\n",
|
||||
buf[0],buf[1],buf[2],buf[3]);
|
||||
break;
|
||||
case 12: printf("^L\n"); break;
|
||||
case 13: printf("intro\n"); break;
|
||||
case 18: printf("^R\n"); break;
|
||||
case 9: printf("tab\n"); break;
|
||||
case 3: printf("control-c\n"); break;
|
||||
case 0: printf("control-space\n"); break;
|
||||
default:
|
||||
printf("(code:%d)\n", buf[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
r_cons_set_raw(0);
|
||||
|
|
@ -365,7 +367,7 @@ int r_line_printchar()
|
|||
}
|
||||
|
||||
/* main readline function */
|
||||
char *r_line_readline(int argc, const char **argv)
|
||||
R_API char *r_line_readline(int argc, const char **argv)
|
||||
{
|
||||
int buf[10];
|
||||
int i, len = 0;
|
||||
|
|
@ -509,7 +511,9 @@ char *r_line_readline(int argc, const char **argv)
|
|||
switch(buf[1]) {
|
||||
case 0x33: // supr
|
||||
if (r_line_buffer_idx<r_line_buffer_len)
|
||||
strcpy(r_line_buffer, r_line_buffer+1);
|
||||
strcpy(r_line_buffer+r_line_buffer_idx,
|
||||
r_line_buffer+r_line_buffer_idx+1);
|
||||
buf[1] = r_line_readchar();
|
||||
break;
|
||||
/* arrows */
|
||||
case 0x41:
|
||||
|
|
|
|||
Loading…
Reference in a new issue