Fix string parsing in rabin2 -z and more random fixes
- Random changes in libr/db/pair.. still buggy - remove debug printfs from calc.c - ?k command is now more usable. supports ``..` strings - fix segfault in r_cons (nullptr) - Add support for !! command to use r_cons > pd|!grep eax~ebx # now this command works
This commit is contained in:
parent
b0163bfdef
commit
7a4a3dbbfd
1
AUTHORS
1
AUTHORS
|
@ -20,5 +20,6 @@ Contributors: (sorted by length)
|
|||
- rudi_s
|
||||
- vext01
|
||||
- l0gic
|
||||
- eddyb
|
||||
- graz
|
||||
- pof
|
||||
|
|
4
TODO
4
TODO
|
@ -5,10 +5,6 @@
|
|||
|
||||
------8<-------------------8<--------------------8<-----------------8<----------
|
||||
|
||||
* add pf to the manpage in r2
|
||||
* r2 -n VG fails
|
||||
* VB /* fails
|
||||
* remove my nick/mail from valabind version
|
||||
|
||||
====[[ 0.9.1 ]]====
|
||||
|
||||
|
|
|
@ -319,12 +319,8 @@ int main(int argc, char **argv) {
|
|||
|
||||
while ((c = getopt (argc, argv, "Af:a:B:b:c:CdMm:n:@:VisSzIHelRwO:o:p:rvLhx")) != -1) {
|
||||
switch(c) {
|
||||
case 'A':
|
||||
action |= ACTION_LISTARCHS;
|
||||
break;
|
||||
case 'a':
|
||||
if (optarg) arch = strdup (optarg);
|
||||
break;
|
||||
case 'A': action |= ACTION_LISTARCHS; break;
|
||||
case 'a': if (optarg) arch = strdup (optarg); break;
|
||||
case 'c':
|
||||
if (!optarg) {
|
||||
eprintf ("Missing argument for -c");
|
||||
|
@ -333,58 +329,26 @@ int main(int argc, char **argv) {
|
|||
action = ACTION_CREATE;
|
||||
create = strdup (optarg);
|
||||
break;
|
||||
case 'C':
|
||||
action |= ACTION_CLASSES;
|
||||
break;
|
||||
case 'f':
|
||||
if (optarg) arch_name = strdup (optarg);
|
||||
break;
|
||||
case 'b':
|
||||
bits = r_num_math (NULL, optarg);
|
||||
break;
|
||||
case 'C': action |= ACTION_CLASSES; break;
|
||||
case 'f': if (optarg) arch_name = strdup (optarg); break;
|
||||
case 'b': bits = r_num_math (NULL, optarg); break;
|
||||
case 'm':
|
||||
at = r_num_math (NULL, optarg);
|
||||
action |= ACTION_SRCLINE;
|
||||
break;
|
||||
case 'i':
|
||||
action |= ACTION_IMPORTS;
|
||||
break;
|
||||
case 's':
|
||||
action |= ACTION_SYMBOLS;
|
||||
break;
|
||||
case 'S':
|
||||
action |= ACTION_SECTIONS;
|
||||
break;
|
||||
case 'z':
|
||||
action |= ACTION_STRINGS;
|
||||
break;
|
||||
case 'I':
|
||||
action |= ACTION_INFO;
|
||||
break;
|
||||
case 'H':
|
||||
action |= ACTION_FIELDS;
|
||||
break;
|
||||
case 'd':
|
||||
action |= ACTION_DWARF;
|
||||
break;
|
||||
case 'e':
|
||||
action |= ACTION_ENTRIES;
|
||||
break;
|
||||
case 'M':
|
||||
action |= ACTION_MAIN;
|
||||
break;
|
||||
case 'l':
|
||||
action |= ACTION_LIBS;
|
||||
break;
|
||||
case 'R':
|
||||
action |= ACTION_RELOCS;
|
||||
break;
|
||||
case 'x':
|
||||
action |= ACTION_EXTRACT;
|
||||
break;
|
||||
case 'w':
|
||||
rw = R_TRUE;
|
||||
break;
|
||||
case 'i': action |= ACTION_IMPORTS; break;
|
||||
case 's': action |= ACTION_SYMBOLS; break;
|
||||
case 'S': action |= ACTION_SECTIONS; break;
|
||||
case 'z': action |= ACTION_STRINGS; break;
|
||||
case 'I': action |= ACTION_INFO; break;
|
||||
case 'H': action |= ACTION_FIELDS; break;
|
||||
case 'd': action |= ACTION_DWARF; break;
|
||||
case 'e': action |= ACTION_ENTRIES; break;
|
||||
case 'M': action |= ACTION_MAIN; break;
|
||||
case 'l': action |= ACTION_LIBS; break;
|
||||
case 'R': action |= ACTION_RELOCS; break;
|
||||
case 'x': action |= ACTION_EXTRACT; break;
|
||||
case 'w': rw = R_TRUE; break;
|
||||
case 'O':
|
||||
op = optarg;
|
||||
action |= ACTION_OPERATION;
|
||||
|
@ -394,30 +358,14 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
// return rabin_do_operation (op);
|
||||
break;
|
||||
case 'o':
|
||||
output = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
rad = R_TRUE;
|
||||
break;
|
||||
case 'v':
|
||||
va = R_TRUE;
|
||||
break;
|
||||
case 'L':
|
||||
r_bin_list (bin);
|
||||
return 1;
|
||||
case 'B':
|
||||
gbaddr = r_num_math (NULL, optarg);
|
||||
break;
|
||||
case '@':
|
||||
at = r_num_math (NULL, optarg);
|
||||
break;
|
||||
case 'n':
|
||||
name = optarg;
|
||||
break;
|
||||
case 'V':
|
||||
printf ("rabin2 v"R2_VERSION"\n");
|
||||
return 0;
|
||||
case 'o': output = optarg; break;
|
||||
case 'r': rad = R_TRUE; break;
|
||||
case 'v': va = R_TRUE; break;
|
||||
case 'L': r_bin_list (bin); return 1;
|
||||
case 'B': gbaddr = r_num_math (NULL, optarg); break;
|
||||
case '@': at = r_num_math (NULL, optarg); break;
|
||||
case 'n': name = optarg; break;
|
||||
case 'V': printf ("rabin2 v"R2_VERSION"\n"); return 0;
|
||||
case 'h':
|
||||
default:
|
||||
action |= ACTION_HELP;
|
||||
|
|
|
@ -27,10 +27,15 @@ static void get_strings_range(RBinArch *arch, RList *list, int min, ut64 from, u
|
|||
return;
|
||||
}
|
||||
for (i = from; i < to; i++) {
|
||||
if ((IS_PRINTABLE (arch->buf->buf[i])) && matches < R_BIN_SIZEOF_STRINGS-1) {
|
||||
if ((IS_PRINTABLE (arch->buf->buf[i])) && \
|
||||
matches < R_BIN_SIZEOF_STRINGS-1) {
|
||||
str[matches] = arch->buf->buf[i];
|
||||
if (arch->buf->buf[i+1]==0 && IS_PRINTABLE (arch->buf->buf[i+2]))
|
||||
i++;
|
||||
/* add support for wide char strings */
|
||||
if (arch->buf->buf[i+1]==0) {
|
||||
if (IS_PRINTABLE (arch->buf->buf[i+2]))
|
||||
if (arch->buf->buf[i+3]==0)
|
||||
i++;
|
||||
}
|
||||
matches++;
|
||||
continue;
|
||||
}
|
||||
|
@ -49,7 +54,7 @@ static void get_strings_range(RBinArch *arch, RList *list, int min, ut64 from, u
|
|||
// copying so many bytes here..
|
||||
memcpy (ptr->string, str, R_BIN_SIZEOF_STRINGS);
|
||||
ptr->string[R_BIN_SIZEOF_STRINGS-1] = '\0';
|
||||
r_name_filter (ptr->string, R_BIN_SIZEOF_STRINGS-1);
|
||||
//r_name_filter (ptr->string, R_BIN_SIZEOF_STRINGS-1);
|
||||
r_list_append (list, ptr);
|
||||
ctr++;
|
||||
}
|
||||
|
@ -238,8 +243,8 @@ R_API void* r_bin_free(RBin *bin) {
|
|||
r_bin_free_items (bin);
|
||||
if (bin->curxtr && bin->curxtr->destroy)
|
||||
bin->curxtr->destroy (bin);
|
||||
r_list_free(bin->binxtrs);
|
||||
r_list_free(bin->plugins);
|
||||
r_list_free (bin->binxtrs);
|
||||
r_list_free (bin->plugins);
|
||||
free (bin->file);
|
||||
free (bin);
|
||||
return NULL;
|
||||
|
@ -484,7 +489,6 @@ R_API RBinObj *r_bin_get_object(RBin *bin, int flags) {
|
|||
}
|
||||
|
||||
R_API void r_bin_object_free(RBinObj *obj) {
|
||||
// XXX: leak
|
||||
free (obj);
|
||||
}
|
||||
|
||||
|
|
|
@ -352,7 +352,7 @@ R_API int r_cons_get_column() {
|
|||
|
||||
/* final entrypoint for adding stuff in the buffer screen */
|
||||
R_API void r_cons_memcat(const char *str, int len) {
|
||||
if (len>0) {
|
||||
if (str && len>0) {
|
||||
palloc (len+1);
|
||||
memcpy (I.buffer+I.buffer_len, str, len+1);
|
||||
I.buffer_len += len;
|
||||
|
|
|
@ -18,12 +18,14 @@ static int bin_strings (RCore *r, int mode, ut64 baddr, int va) {
|
|||
r_list_foreach (list, iter, string) {
|
||||
/* Jump the withespaces before the string */
|
||||
for (i=0; *(string->string+i)==' '; i++);
|
||||
r_meta_add (r->anal->meta, R_META_TYPE_STRING, va?baddr+string->rva:string->offset,
|
||||
(va?baddr+string->rva:string->offset)+string->size, string->string+i);
|
||||
r_meta_add (r->anal->meta, R_META_TYPE_STRING,
|
||||
va?baddr+string->rva:string->offset,
|
||||
(va?baddr+string->rva:string->offset)+string->size, string->string+i);
|
||||
r_name_filter (string->string, 128);
|
||||
snprintf (str, R_FLAG_NAME_SIZE, "str.%s", string->string);
|
||||
r_flag_set (r->flags, str, va?baddr+string->rva:string->offset,
|
||||
string->size, 0);
|
||||
r_flag_set (r->flags, str,
|
||||
va? baddr+string->rva:string->offset,
|
||||
string->size, 0);
|
||||
}
|
||||
} else {
|
||||
if (mode) r_cons_printf ("fs strings\n");
|
||||
|
|
|
@ -379,26 +379,69 @@ static int cmd_visual(void *data, const char *input) {
|
|||
|
||||
static int cmd_system(void *data, const char *input) {
|
||||
int ret = 0;
|
||||
if (*input!='?') {
|
||||
switch (*input) {
|
||||
case '!': {
|
||||
int olen;
|
||||
char *out = NULL;
|
||||
char *cmd = r_core_sysenv_begin ((RCore*)data, input);
|
||||
if (cmd) {
|
||||
ret = r_sys_cmd_str_full (cmd+1, NULL, &out, &olen, NULL);
|
||||
r_core_sysenv_end ((RCore*)data, input);
|
||||
r_cons_memcat (out, olen);
|
||||
free (out);
|
||||
free (cmd);
|
||||
} else eprintf ("Error setting up system environment\n");
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
r_core_sysenv_help ();
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char *cmd = r_core_sysenv_begin ((RCore*)data, input);
|
||||
if (cmd) {
|
||||
ret = r_sys_cmd (cmd);
|
||||
r_core_sysenv_end ((RCore*)data, input);
|
||||
free (cmd);
|
||||
} else eprintf ("Error setting up system environment\n");
|
||||
} else r_core_sysenv_help ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int r_core_cmd_pipe(RCore *core, char *radare_cmd, char *shell_cmd) {
|
||||
char *_ptr;
|
||||
#if __UNIX__
|
||||
int fds[2];
|
||||
int stdout_fd, status = 0;
|
||||
#endif
|
||||
if (*shell_cmd=='!') {
|
||||
_ptr = (char *)r_str_lastbut (shell_cmd, '~', "\"");
|
||||
//ptr = strchr (cmd, '~');
|
||||
if (_ptr) {
|
||||
*_ptr = '\0';
|
||||
_ptr++;
|
||||
}
|
||||
int olen = 0, ret;
|
||||
char *str, *out = NULL;
|
||||
// TODO: implement foo
|
||||
str = r_core_cmd_str (core, radare_cmd);
|
||||
ret = r_sys_cmd_str_full (shell_cmd+1, str, &out, &olen, NULL);
|
||||
r_cons_memcat (out, olen);
|
||||
if (_ptr)
|
||||
r_cons_grep (_ptr);
|
||||
free (out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if __UNIX__
|
||||
radare_cmd = (char*)r_str_trim_head (radare_cmd);
|
||||
shell_cmd = (char*)r_str_trim_head (shell_cmd);
|
||||
|
||||
stdout_fd = dup (1);
|
||||
pipe (fds);
|
||||
radare_cmd = (char*)r_str_trim_head (radare_cmd);
|
||||
shell_cmd = (char*)r_str_trim_head (shell_cmd);
|
||||
eprintf ("CMDPIPE (%s)\n", shell_cmd);
|
||||
if (fork ()) {
|
||||
dup2 (fds[1], 1);
|
||||
close (fds[1]);
|
||||
|
@ -447,6 +490,7 @@ static int r_core_cmd_subst(RCore *core, char *cmd) {
|
|||
static int r_core_cmd_subst_i(RCore *core, char *cmd) {
|
||||
char *ptr, *ptr2, *str;
|
||||
int i, len = strlen (cmd), pipefd, ret;
|
||||
const char *tick = NULL;
|
||||
const char *quotestr = "\"`";
|
||||
quotestr = "`"; // tmp
|
||||
|
||||
|
@ -502,11 +546,16 @@ static int r_core_cmd_subst_i(RCore *core, char *cmd) {
|
|||
//ptr = strchr (cmd, '|');
|
||||
ptr = (char *)r_str_lastbut (cmd, '|', quotestr);
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
cmd = r_str_clean (cmd);
|
||||
if (*cmd) r_core_cmd_pipe (core, cmd, ptr+1);
|
||||
else r_io_system (core->io, ptr+1);
|
||||
return 0;
|
||||
char *ptr2 = strchr (cmd, '`');
|
||||
if (!ptr2 || ptr2 && ptr2>ptr) {
|
||||
if (!tick || (tick && tick > ptr)) {
|
||||
*ptr = '\0';
|
||||
cmd = r_str_clean (cmd);
|
||||
if (*cmd) r_core_cmd_pipe (core, cmd, ptr+1);
|
||||
else r_io_system (core->io, ptr+1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO must honor " and `
|
||||
|
|
|
@ -205,21 +205,47 @@ static int cmd_help(void *data, const char *input) {
|
|||
core->yank_len = core->yank? strlen ((const char *)core->yank): 0;
|
||||
break;
|
||||
case 'k': // key=value utility
|
||||
for (input++; *input==' '; input++);
|
||||
if (*input) {
|
||||
char *p = strchr (input, '=');
|
||||
switch (input[1]) {
|
||||
case ' ':
|
||||
{
|
||||
char *p = strchr (input+1, '=');
|
||||
if (p) {
|
||||
// set
|
||||
*p = 0;
|
||||
r_pair_set (core->kv, input, p+1);
|
||||
r_pair_set (core->kv, input+2, p+1);
|
||||
} else {
|
||||
// get
|
||||
char *g = r_pair_get (core->kv, input);
|
||||
char *g = r_pair_get (core->kv, input+2);
|
||||
if (g) {
|
||||
r_cons_printf ("%s\n", g);
|
||||
free (g);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
r_pair_save (core->kv, input+3);
|
||||
break;
|
||||
case 'l':
|
||||
r_pair_load (core->kv, input+3);
|
||||
break;
|
||||
case '\0':
|
||||
{ RListIter *iter;
|
||||
RPairItem *kv;
|
||||
RList *list = r_pair_list (core->kv, NULL);
|
||||
r_list_foreach (list, iter, kv) {
|
||||
r_cons_printf ("%s=%s\n", kv->k, kv->v);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
eprintf ("Usage: ?k [key[=value]]\n"
|
||||
" ?k foo=bar # set value\n"
|
||||
" ?k foo # show value\n"
|
||||
" ?k # list keys\n"
|
||||
" ?kl ha.sdb # load keyvalue from ha.sdb\n"
|
||||
" ?ks ha.sdb # save keyvalue to ha.sdb\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'i': // input num
|
||||
|
|
|
@ -57,31 +57,32 @@ static int cmd_info(void *data, const char *input) {
|
|||
break;
|
||||
default:
|
||||
if (core->file) {
|
||||
const char *fn = NULL;
|
||||
int dbg = r_config_get_i (core->config, "cfg.debug");
|
||||
RBinInfo *info = r_bin_get_info (core->bin);
|
||||
if (info) {
|
||||
fn = info->file;
|
||||
r_cons_printf ("type\t%s\n", info->type);
|
||||
r_cons_printf ("os\t%s\n", info->os);
|
||||
r_cons_printf ("arch\t%s\n", info->machine);
|
||||
r_cons_printf ("bits\t%d\n", info->bits);
|
||||
r_cons_printf ("endian\t%s\n", info->big_endian? "big": "little");
|
||||
} else {
|
||||
fn = core->file->filename;
|
||||
}
|
||||
r_cons_printf ("file\t%s\n", fn);
|
||||
if (dbg) dbg = R_IO_WRITE | R_IO_EXEC;
|
||||
r_cons_printf ("fd\t%d\n", core->file->fd->fd);
|
||||
r_cons_printf ("size\t0x%x\n", core->file->size);
|
||||
r_cons_printf ("mode\t%s\n", r_str_rwx_i (core->file->rwx | dbg));
|
||||
r_cons_printf ("block\t0x%x\n", core->blocksize);
|
||||
r_cons_printf ("uri\t%s\n", core->file->uri);
|
||||
if (core->bin->curxtr)
|
||||
r_cons_printf ("packet\t%s\n", core->bin->curxtr->name);
|
||||
if (core->bin->curxtr)
|
||||
r_cons_printf ("format\t%s\n", core->bin->curarch.curplugin->name);
|
||||
} else eprintf ("No selected file\n");
|
||||
eprintf ("No selected file\n");
|
||||
return R_FALSE;
|
||||
} {
|
||||
const char *fn = NULL;
|
||||
int dbg = r_config_get_i (core->config, "cfg.debug");
|
||||
RBinInfo *info = r_bin_get_info (core->bin);
|
||||
if (info) {
|
||||
fn = info->file;
|
||||
r_cons_printf ("type\t%s\n", info->type);
|
||||
r_cons_printf ("os\t%s\n", info->os);
|
||||
r_cons_printf ("arch\t%s\n", info->machine);
|
||||
r_cons_printf ("bits\t%d\n", info->bits);
|
||||
r_cons_printf ("endian\t%s\n", info->big_endian? "big": "little");
|
||||
} else fn = core->file->filename;
|
||||
r_cons_printf ("file\t%s\n", fn);
|
||||
if (dbg) dbg = R_IO_WRITE | R_IO_EXEC;
|
||||
r_cons_printf ("fd\t%d\n", core->file->fd->fd);
|
||||
r_cons_printf ("size\t0x%x\n", core->file->size);
|
||||
r_cons_printf ("mode\t%s\n", r_str_rwx_i (core->file->rwx | dbg));
|
||||
r_cons_printf ("block\t0x%x\n", core->blocksize);
|
||||
r_cons_printf ("uri\t%s\n", core->file->uri);
|
||||
if (core->bin->curxtr)
|
||||
r_cons_printf ("packet\t%s\n", core->bin->curxtr->name);
|
||||
if (core->bin->curxtr)
|
||||
r_cons_printf ("format\t%s\n", core->bin->curarch.curplugin->name);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -350,7 +350,8 @@ R_API int r_core_init(RCore *core) {
|
|||
core->reflines2 = NULL;
|
||||
core->yank_len = 0;
|
||||
core->yank_off = 0LL;
|
||||
core->kv = r_pair_new ();
|
||||
//core->kv = r_pair_new ();
|
||||
core->kv = r_pair_new_from_file ("r2kv.sdb");
|
||||
core->num = r_num_new (&num_callback, core);
|
||||
//core->num->callback = &num_callback;
|
||||
//core->num->userptr = core;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2010-2011 - nibble<develsec.org> */
|
||||
/* radare - LGPL - Copyright 2010-2012 - nibble<develsec.org> */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -1,19 +1,53 @@
|
|||
/* radare - LGPL - Copyright 2011 pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2011-2012 pancake<nopcode.org> */
|
||||
|
||||
#include <r_db.h>
|
||||
#include <r_util.h>
|
||||
#include "sdb/src/sdb.h"
|
||||
|
||||
/*
|
||||
var p = new Pair ();
|
||||
p.set ("foo", "bar")
|
||||
var out = p.get ("foo")
|
||||
*/
|
||||
R_API void r_pair_set_file (RPair*p, const char *file) {
|
||||
if (!file || !*file) return;
|
||||
if (p->file) free (p->file);
|
||||
p->file = strdup (file);
|
||||
if (p->sdb) {
|
||||
Sdb *sdb = p->sdb;
|
||||
sdb->dir = p->file;
|
||||
} else eprintf ("no sdb set\n");
|
||||
}
|
||||
|
||||
R_API void r_pair_fini(RPair *p) {
|
||||
r_hashtable_free (p->ht);
|
||||
r_list_free (p->dbs);
|
||||
if (p->file) {
|
||||
free (p->file);
|
||||
// memleak
|
||||
//sdb_free (p->sdb);
|
||||
p->sdb = NULL;
|
||||
}
|
||||
free (p->dir);
|
||||
}
|
||||
|
||||
R_API int r_pair_save(RPair *p, const char *f) {
|
||||
r_pair_set_file (p, f);
|
||||
return r_pair_sync (p);
|
||||
}
|
||||
|
||||
R_API int r_pair_load(RPair *p, const char *f) {
|
||||
RPair *p2;
|
||||
char *file = (f&&*f)? strdup (f): p->file? strdup (p->file): NULL;
|
||||
r_pair_set_file (p, f);
|
||||
r_pair_fini (p);
|
||||
if (!file) return R_FALSE;
|
||||
p2 = r_pair_new_from_file (file);
|
||||
memcpy (p, p2, sizeof (RPair));
|
||||
free (p2);
|
||||
free (file);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API RPair *r_pair_new () {
|
||||
RPair *p = R_NEW0 (RPair);
|
||||
p->file = NULL;
|
||||
p->sdb = NULL;
|
||||
p->sdb = sdb_new (NULL, 0);
|
||||
p->ht = r_hashtable_new ();
|
||||
p->dbs = r_list_new ();
|
||||
p->dbs->free = (RListFree)sdb_free;
|
||||
|
@ -29,13 +63,7 @@ R_API RPair *r_pair_new_from_file (const char *file) {
|
|||
|
||||
R_API void r_pair_free (RPair *p) {
|
||||
if (p==NULL) return;
|
||||
r_hashtable_free (p->ht);
|
||||
r_list_free (p->dbs);
|
||||
if (p->file) {
|
||||
free (p->file);
|
||||
sdb_free (p->sdb);
|
||||
}
|
||||
free (p->dir);
|
||||
r_pair_fini (p);
|
||||
free (p);
|
||||
}
|
||||
|
||||
|
@ -100,9 +128,9 @@ R_API char *r_pair_get (RPair *p, const char *name) {
|
|||
}
|
||||
|
||||
R_API void r_pair_set (RPair *p, const char *name, const char *value) {
|
||||
Sdb *sdb;
|
||||
char *dom, *key, *okey;
|
||||
ut32 hdom;
|
||||
char *dom, *key;
|
||||
Sdb *sdb;
|
||||
|
||||
if (p->file) {
|
||||
sdb_set (p->sdb, name, value);
|
||||
|
@ -111,26 +139,21 @@ R_API void r_pair_set (RPair *p, const char *name, const char *value) {
|
|||
key = strdup (name);
|
||||
dom = r_str_lchr (key, '.');
|
||||
if (dom) {
|
||||
char *okey = key;
|
||||
okey = key;
|
||||
*dom = 0;
|
||||
key = dom+1;
|
||||
dom = okey;
|
||||
} else dom = "";
|
||||
hdom = r_str_hash (dom);
|
||||
sdb = r_hashtable_lookup (p->ht, hdom);
|
||||
if (!sdb)
|
||||
sdb = pair_sdb_new (p, dom, hdom);
|
||||
if (!sdb) sdb = pair_sdb_new (p, dom, hdom);
|
||||
sdb_set (sdb, key, value);
|
||||
}
|
||||
|
||||
R_API RList *r_pair_list (RPair *p, const char *domain) {
|
||||
Sdb *s;
|
||||
if (p->file) {
|
||||
s = p->sdb;
|
||||
} else {
|
||||
ut32 hdom = r_str_hash (domain);
|
||||
s = r_hashtable_lookup (p->ht, hdom);
|
||||
}
|
||||
if (p->file) s = p->sdb;
|
||||
else s = r_hashtable_lookup (p->ht, r_str_hash (domain));
|
||||
if (s) {
|
||||
RList *list = r_list_new ();
|
||||
char key[SDB_KEYSIZE];
|
||||
|
@ -169,14 +192,12 @@ R_API void r_pair_reset (RPair *p) {
|
|||
sdb_reset (s);
|
||||
}
|
||||
|
||||
R_API void r_pair_sync (RPair *p) {
|
||||
R_API int r_pair_sync (RPair *p) {
|
||||
Sdb *s;
|
||||
char *old = NULL;
|
||||
RListIter *iter;
|
||||
if (p->file) {
|
||||
sdb_sync (p->sdb);
|
||||
return;
|
||||
}
|
||||
if (p->file)
|
||||
return sdb_sync (p->sdb);
|
||||
if (p->dir) {
|
||||
old = r_sys_getdir ();
|
||||
r_sys_rmkdir (p->dir);
|
||||
|
@ -189,6 +210,7 @@ R_API void r_pair_sync (RPair *p) {
|
|||
r_sys_chdir (old);
|
||||
free (old);
|
||||
}
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API char* r_pair_serialize(RPair *p, const char *fmt, void *ptr) {
|
||||
|
|
|
@ -67,6 +67,8 @@ typedef struct r_pair_item_t {
|
|||
R_API RPairItem *r_pair_item_new ();
|
||||
R_API void r_pair_item_free (RPairItem*);
|
||||
|
||||
R_API int r_pair_load(RPair *p, const char *f);
|
||||
R_API int r_pair_save(RPair *p, const char *f);
|
||||
R_API RPair *r_pair_new ();
|
||||
R_API RPair *r_pair_new_from_file (const char *file);
|
||||
R_API void r_pair_free (RPair *p);
|
||||
|
@ -75,8 +77,7 @@ R_API char *r_pair_get (RPair *p, const char *name);
|
|||
R_API void r_pair_set (RPair *p, const char *name, const char *value);
|
||||
R_API RList *r_pair_list (RPair *p, const char *domain);
|
||||
R_API void r_pair_set_sync_dir (RPair *p, const char *dir);
|
||||
R_API void r_pair_load (RPair *p);
|
||||
R_API void r_pair_sync (RPair *p);
|
||||
R_API int r_pair_sync (RPair *p);
|
||||
R_API void r_pair_reset (RPair *p);
|
||||
/* */
|
||||
R_API struct r_db_t *r_db_new();
|
||||
|
|
|
@ -253,7 +253,6 @@ static RNumToken get_token() {
|
|||
int i = 0;
|
||||
string_value[i++] = ch;
|
||||
if (ch == '[') {
|
||||
eprintf ("laraalalala\n");
|
||||
while (cin_get (&ch) && ch!=']') {
|
||||
if (i>=STRSZ) {
|
||||
error ("string too long");
|
||||
|
@ -261,7 +260,6 @@ eprintf ("laraalalala\n");
|
|||
}
|
||||
string_value[i++] = ch;
|
||||
}
|
||||
eprintf ("BREAK (%c)\n", ch);
|
||||
string_value[i++] = ch;
|
||||
} else {
|
||||
while (cin_get (&ch) && isvalidchar (ch)) {
|
||||
|
|
|
@ -83,7 +83,7 @@ execute (just-in-time)
|
|||
exit@syscall(1);
|
||||
.Pp
|
||||
main@global(128) {
|
||||
.var0 = "hi!\n";
|
||||
.var0 = "hi!\\n";
|
||||
write(1,.var0, 4);
|
||||
exit(0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue