* Fix DEX parsing segfault
* Fix possible segfault on newer glibc * Fix some indentations and Visual hints
This commit is contained in:
parent
e0f8869e1b
commit
bf95651e69
38
TODO
38
TODO
|
@ -3,13 +3,31 @@
|
|||
| < V . | . V . < _/ .-' _/| () |
|
||||
|__\__|_|__|___/__|__|_\__\___/ |____(_)____/
|
||||
|
||||
CODENAME: #DRY
|
||||
|
||||
* Proper support for MACH-O binaries
|
||||
* Analyze this opcode:
|
||||
0x100005e52 0 ff2518130000 jmp qword [rip+0x1318]
|
||||
* x86/32-x86/64 the -e asm.bits should
|
||||
* Make r_io happy with RList
|
||||
[[ 0.8 ]] -- TODO
|
||||
* Tracing features for the debugger
|
||||
* We need a 64 bit x86 assembler working!! nasm fails
|
||||
* Proper support for MACH-O binaries
|
||||
- rabin2 -f works? i think its used with '-a'
|
||||
- I think symbols are not correct .. (offset+disk)
|
||||
* If [0-9] keybindings in visual point to same address use same reference
|
||||
|
||||
[[ 0.8 ]] -- BUGS to be fixed
|
||||
* Handle ^C in searches (at least)
|
||||
* Analyze this opcode: ff2518130000 jmp qword [rip+0x1318]
|
||||
|
||||
[[ 0.8 ]] -- refactoring tasks
|
||||
* Make r_io happy with RList
|
||||
* Add r_cons_prompt () ... calling set_prompt + fgets -- this api needs cleanup
|
||||
- set prompt, set line, fgets
|
||||
- strict width in visual
|
||||
* Dupped javasm bin/asm
|
||||
* REFACTORING of disasm loop XDDDDD -1 (r2-0.8 plzz)
|
||||
- arch dependent anal code must be removed from disasm loop +1
|
||||
|
||||
|
||||
------8<-------------------8<--------------------8<-----------------8<----------
|
||||
|
||||
To wipe:
|
||||
========
|
||||
|
@ -20,21 +38,13 @@ To wipe:
|
|||
|
||||
To do:
|
||||
======
|
||||
* Handle ^C in searches (at least)
|
||||
* libmagic internal :? -- find a decent implementation and adopt it
|
||||
* Ranged/scrollable zoom mode
|
||||
* Add r_cons_prompt () ... calling set_prompt + fgets -- this api needs cleanup
|
||||
- strict width in visual
|
||||
* If [0-9] keybindings in visual point to same address use same reference
|
||||
* Honor string metadata for asmsteps ('jk' in visual)
|
||||
* Dupped javasm bin/asm
|
||||
* REFACTORING of disasm loop XDDDDD -1 (r2-0.8 plzz)
|
||||
- arch dependent anal code must be removed from disasm loop +1
|
||||
|
||||
pancake
|
||||
-------
|
||||
* check search multiple keywords and signatures
|
||||
* Visual disassembly cursor does not displays on scr.color=0
|
||||
* if console width > X place comments there (ash)
|
||||
* Implement BLOCK in r_core_sysenv_begin|end ()
|
||||
* Fix iterators for r_macro (test only?)
|
||||
|
@ -86,7 +96,7 @@ earada
|
|||
* p7 : 7bit encoding (sms)
|
||||
* Add print support for bitfields (pm b...)
|
||||
* Fix io_haret memory dump
|
||||
* r_socket
|
||||
* r_socket (already done?)
|
||||
- Add SSL support
|
||||
- http API in r_socket module
|
||||
- allow to get/post data/files with continue on plain/ssl
|
||||
|
|
|
@ -580,8 +580,7 @@ static int rabin_do_operation(const char *op) {
|
|||
if (ptr2) {
|
||||
if (!rabin_dump_symbols (r_num_math(NULL, ptr2)))
|
||||
return R_FALSE;
|
||||
} else
|
||||
if (!rabin_dump_symbols (0))
|
||||
} else if (!rabin_dump_symbols (0))
|
||||
return R_FALSE;
|
||||
} else if (ptr[0]=='S') {
|
||||
if (!ptr2)
|
||||
|
@ -751,8 +750,7 @@ int main(int argc, char **argv) {
|
|||
if (action == ACTION_HELP || action == ACTION_UNK || file == NULL)
|
||||
return rabin_show_help ();
|
||||
|
||||
if (!r_bin_load (bin, file, R_FALSE) &&
|
||||
!r_bin_load (bin, file, R_TRUE)) {
|
||||
if (!r_bin_load (bin, file, R_FALSE) && !r_bin_load (bin, file, R_TRUE)) {
|
||||
eprintf ("r_bin: Cannot open '%s'\n", file);
|
||||
return 1;
|
||||
}
|
||||
|
@ -764,13 +762,13 @@ int main(int argc, char **argv) {
|
|||
bits = r_num_math (NULL, ptr+1);
|
||||
}
|
||||
}
|
||||
if (action&ACTION_LISTARCHS ||
|
||||
((arch || bits || arch_name) &&
|
||||
!r_bin_set_arch (bin, arch, bits, arch_name))) {
|
||||
r_bin_list_archs (bin);
|
||||
free (arch);
|
||||
r_bin_free (bin);
|
||||
return 1;
|
||||
if (action & ACTION_LISTARCHS && (arch || bits || arch_name)) {
|
||||
if (!r_bin_set_arch (bin, arch, bits, arch_name)) {
|
||||
r_bin_list_archs (bin);
|
||||
free (arch);
|
||||
r_bin_free (bin);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (action&ACTION_SECTIONS)
|
||||
|
@ -796,7 +794,7 @@ int main(int argc, char **argv) {
|
|||
if (action&ACTION_SRCLINE)
|
||||
rabin_show_srcline(at);
|
||||
if (action&ACTION_EXTRACT)
|
||||
rabin_extract ((arch==NULL&&arch_name==NULL&&bits==0));
|
||||
rabin_extract ((arch==NULL && arch_name==NULL && bits==0));
|
||||
if (op != NULL && action&ACTION_OPERATION)
|
||||
rabin_do_operation (op);
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
char* r_bin_dex_get_version(struct r_bin_dex_obj_t* bin) {
|
||||
char *version = malloc (8);
|
||||
|
||||
memset (version, 0, 8);
|
||||
memcpy (version, bin->b->buf+4, 3);
|
||||
return version;
|
||||
|
@ -18,60 +17,60 @@ struct r_bin_dex_obj_t* r_bin_dex_new_buf(struct r_buf_t *buf) {
|
|||
memset (bin, 0, sizeof (struct r_bin_dex_obj_t));
|
||||
bin->b = buf;
|
||||
bin->size = buf->length;
|
||||
r_buf_read_at(bin->b, 0, (ut8*)&bin->header, sizeof (struct dex_header_t));
|
||||
r_buf_read_at (bin->b, 0, (ut8*)&bin->header, sizeof (struct dex_header_t));
|
||||
return bin;
|
||||
}
|
||||
|
||||
// Move to r_util ??
|
||||
int dex_read_uleb128 (const char *ptr) {
|
||||
int cur, result = *(ptr++);
|
||||
int cur, result = *(ptr++);
|
||||
|
||||
if (result > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result = (result & 0x7f) | ((cur & 0x7f) << 7);
|
||||
if (cur > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 14;
|
||||
if (cur > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 21;
|
||||
if (cur > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result |= cur << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
if (result > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result = (result & 0x7f) | ((cur & 0x7f) << 7);
|
||||
if (cur > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 14;
|
||||
if (cur > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 21;
|
||||
if (cur > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result |= cur << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#define SIG_EXTEND(X,Y) X = (X << Y) >> Y
|
||||
int dex_read_sleb128 (const char *ptr) {
|
||||
int cur, result = *(ptr++);
|
||||
int cur, result = *(ptr++);
|
||||
|
||||
if (result <= 0x7f) {
|
||||
if (result <= 0x7f) {
|
||||
SIG_EXTEND (result, 25);
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result = (result & 0x7f) | ((cur & 0x7f) << 7);
|
||||
if (cur <= 0x7f) {
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result = (result & 0x7f) | ((cur & 0x7f) << 7);
|
||||
if (cur <= 0x7f) {
|
||||
SIG_EXTEND (result, 18);
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 14;
|
||||
if (cur <= 0x7f) {
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 14;
|
||||
if (cur <= 0x7f) {
|
||||
SIG_EXTEND (result, 11);
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 21;
|
||||
if (cur <= 0x7f) {
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 21;
|
||||
if (cur <= 0x7f) {
|
||||
SIG_EXTEND (result, 4);
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result |= cur << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result |= cur << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -4,28 +4,28 @@
|
|||
|
||||
struct dex_header_t {
|
||||
ut8 magic[8];
|
||||
ut32 checksum;
|
||||
ut8 signature[20];
|
||||
ut32 size;
|
||||
ut32 header_size;
|
||||
ut32 endian;
|
||||
ut32 linksection_size;
|
||||
ut32 linksection_offset;
|
||||
ut32 map_offset;
|
||||
ut32 strings_size;
|
||||
ut32 strings_offset;
|
||||
ut32 types_size;
|
||||
ut32 types_offset;
|
||||
ut32 prototypes_size;
|
||||
ut32 prototypes_offset;
|
||||
ut32 fields_size;
|
||||
ut32 fields_offset;
|
||||
ut32 method_size;
|
||||
ut32 method_offset;
|
||||
ut32 class_size;
|
||||
ut32 class_offset;
|
||||
ut32 data_size;
|
||||
ut32 data_offset;
|
||||
ut32 checksum;
|
||||
ut8 signature[20];
|
||||
ut32 size;
|
||||
ut32 header_size;
|
||||
ut32 endian;
|
||||
ut32 linksection_size;
|
||||
ut32 linksection_offset;
|
||||
ut32 map_offset;
|
||||
ut32 strings_size;
|
||||
ut32 strings_offset;
|
||||
ut32 types_size;
|
||||
ut32 types_offset;
|
||||
ut32 prototypes_size;
|
||||
ut32 prototypes_offset;
|
||||
ut32 fields_size;
|
||||
ut32 fields_offset;
|
||||
ut32 method_size;
|
||||
ut32 method_offset;
|
||||
ut32 class_size;
|
||||
ut32 class_offset;
|
||||
ut32 data_size;
|
||||
ut32 data_offset;
|
||||
};
|
||||
|
||||
struct dex_class_t {
|
||||
|
@ -41,7 +41,7 @@ struct dex_class_t {
|
|||
|
||||
struct r_bin_dex_obj_t {
|
||||
int size;
|
||||
const char* file;
|
||||
const char* file;
|
||||
struct r_buf_t* b;
|
||||
struct dex_header_t header;
|
||||
};
|
||||
|
@ -58,6 +58,5 @@ char* r_bin_dex_get_version(struct r_bin_dex_obj_t* bin);
|
|||
struct r_bin_dex_obj_t* r_bin_dex_new_buf(struct r_buf_t *buf);
|
||||
struct r_bin_dex_str_t *r_bin_dex_get_strings (struct r_bin_dex_obj_t* bin);
|
||||
|
||||
|
||||
int dex_read_uleb128 (const char *ptr);
|
||||
int dex_read_sleb128 (const char *ptr);
|
||||
|
|
|
@ -94,8 +94,8 @@ static RList* classes (RBinArch *arch) {
|
|||
return NULL;
|
||||
ret->free = free;
|
||||
for (i = 0; i < bin->header.class_size; i++) {
|
||||
r_buf_read_at(bin->b, bin->header.class_offset, (ut8*)&entry,
|
||||
bin->header.class_size * sizeof (struct dex_class_t));
|
||||
r_buf_read_at (bin->b, (ut64) bin->header.class_offset, (ut8*)&entry,
|
||||
sizeof (struct dex_class_t));
|
||||
eprintf ("ut32 class_id = %08x;\n", entry.class_id);
|
||||
eprintf ("ut32 access_flags = %08x;\n", entry.access_flags);
|
||||
eprintf ("ut32 super_class = %08x;\n", entry.super_class);
|
||||
|
|
|
@ -375,8 +375,7 @@ static int r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len,
|
|||
continue;
|
||||
}
|
||||
/* show cursor */
|
||||
if (core->print->cur_enabled &&
|
||||
cursor >= idx && cursor < (idx+asmop.inst_len))
|
||||
if (core->print->cur_enabled && cursor >= idx && cursor < (idx+asmop.inst_len))
|
||||
r_cons_printf ("* ");
|
||||
else r_cons_printf (" ");
|
||||
if (show_bytes) {
|
||||
|
@ -1271,7 +1270,8 @@ static int cmd_yank(void *data, const char *input) {
|
|||
|
||||
static int cmd_quit(void *data, const char *input) {
|
||||
RCore *core = (RCore *)data;
|
||||
switch (input[0]) {
|
||||
if (input)
|
||||
switch (*input) {
|
||||
case '?':
|
||||
r_cons_printf (
|
||||
"Usage: q[!] [retvalue]\n"
|
||||
|
@ -4462,7 +4462,7 @@ R_API int r_core_cmd(RCore *core, const char *cstr, int log) {
|
|||
ocmd = cmd = malloc (len+8192);
|
||||
if (ocmd == NULL)
|
||||
return R_FALSE;
|
||||
strcpy (cmd, cstr);
|
||||
r_str_cpy (cmd, cstr);
|
||||
cmd = r_str_trim_head_tail (cmd);
|
||||
|
||||
rep = atoi (cmd);
|
||||
|
|
|
@ -43,13 +43,13 @@ R_API void r_core_sysenv_end(RCore *core, const char *cmd) {
|
|||
R_API char *r_core_sysenv_begin(RCore *core, const char *cmd) {
|
||||
char buf[64], *ret;
|
||||
#if DISCUSS
|
||||
// EDITOR cfg.editor (vim or so)
|
||||
CURSOR cursor position (offset from curseek)
|
||||
COLOR scr.color?1:0
|
||||
VERBOSE cfg.verbose
|
||||
// only if cmd matches BYTES or BLOCK ?
|
||||
BYTES hexpairs of current block
|
||||
BLOCK temporally file with contents of current block
|
||||
// EDITOR cfg.editor (vim or so)
|
||||
CURSOR cursor position (offset from curseek)
|
||||
COLOR scr.color?1:0
|
||||
VERBOSE cfg.verbose
|
||||
// only if cmd matches BYTES or BLOCK ?
|
||||
BYTES hexpairs of current block
|
||||
BLOCK temporally file with contents of current block
|
||||
#endif
|
||||
if (!core->file)
|
||||
return NULL;
|
||||
|
@ -75,21 +75,21 @@ R_API char *r_core_sysenv_begin(RCore *core, const char *cmd) {
|
|||
}
|
||||
|
||||
R_API int r_core_bin_load(RCore *r, const char *file) {
|
||||
RBinInfo *info;
|
||||
RBinAddr *binmain;
|
||||
RBinObj *obj;
|
||||
RList *list;
|
||||
RListIter *iter;
|
||||
RBinAddr *entry;
|
||||
int va = r->io->va || r->io->debug;
|
||||
char str[R_FLAG_NAME_SIZE];
|
||||
RBinSection *section;
|
||||
RBinSymbol *symbol;
|
||||
RBinReloc *reloc;
|
||||
RBinString *string;
|
||||
RBinImport *import;
|
||||
RBinSection *section;
|
||||
RBinAddr *binmain;
|
||||
RBinReloc *reloc;
|
||||
RListIter *iter;
|
||||
RBinAddr *entry;
|
||||
RBinInfo *info;
|
||||
RBinObj *obj;
|
||||
RList *list;
|
||||
ut64 baddr;
|
||||
int va = r->io->va || r->io->debug;
|
||||
int i = 0;
|
||||
char str[R_FLAG_NAME_SIZE];
|
||||
|
||||
if (file == NULL)
|
||||
file = r->file->filename;
|
||||
|
@ -130,7 +130,8 @@ R_API int r_core_bin_load(RCore *r, const char *file) {
|
|||
r->blocksize, 0);
|
||||
}
|
||||
/* Seek to the last entry point */
|
||||
r_core_seek (r, va?baddr+entry->rva:entry->offset, 0);
|
||||
if (entry)
|
||||
r_core_seek (r, va?baddr+entry->rva:entry->offset, 0);
|
||||
}
|
||||
|
||||
// s -> Symbols
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - Copyright 2009-2010 pancake+nibble */
|
||||
/* radare - Copyright 2009-2011 pancake+nibble */
|
||||
|
||||
#include "r_core.h"
|
||||
#include "r_socket.h"
|
||||
|
|
|
@ -69,7 +69,7 @@ R_API int r_core_visual_trackflags(RCore *core) {
|
|||
r_cons_clear ();
|
||||
|
||||
if (menu) {
|
||||
r_cons_printf ("\n Flags in flagspace '%s'. Press '?' for help.\n\n",
|
||||
r_cons_printf ("Flags in flagspace '%s'. Press '?' for help.\n\n",
|
||||
(core->flags->space_idx==-1)?"*":core->flags->spaces[core->flags->space_idx]);
|
||||
hit = 0;
|
||||
i = j = 0;
|
||||
|
@ -104,7 +104,7 @@ R_API int r_core_visual_trackflags(RCore *core) {
|
|||
}
|
||||
if (*cmd) r_core_cmd (core, cmd, 0);
|
||||
} else {
|
||||
r_cons_printf ("\n Flag spaces:\n\n");
|
||||
r_cons_printf ("Flag spaces:\n\n");
|
||||
hit = 0;
|
||||
for (j=i=0;i<R_FLAG_SPACES_MAX;i++) {
|
||||
if (core->flags->spaces[i]) {
|
||||
|
@ -370,10 +370,10 @@ R_API void r_core_visual_config(RCore *core) {
|
|||
option = j-1;
|
||||
continue;
|
||||
}
|
||||
r_cons_printf("\n Sel:%s \n\n", fs);
|
||||
r_cons_printf ("\n Sel:%s \n\n", fs);
|
||||
break;
|
||||
case 1: // flag selection
|
||||
r_cons_printf("\n Eval variables: (%s)\n\n", fs);
|
||||
r_cons_printf ("\n Eval variables: (%s)\n\n", fs);
|
||||
hit = 0;
|
||||
j = i = 0;
|
||||
// TODO: cut -d '.' -f 1 | sort | uniq !!!
|
||||
|
@ -396,16 +396,16 @@ R_API void r_core_visual_config(RCore *core) {
|
|||
continue;
|
||||
}
|
||||
if (fs2 != NULL)
|
||||
r_cons_printf("\n Selected: %s\n\n", fs2);
|
||||
r_cons_printf ("\n Selected: %s\n\n", fs2);
|
||||
}
|
||||
|
||||
if (fs&&!memcmp (fs, "asm.", 4))
|
||||
r_core_cmd (core, "pd 5", 0);
|
||||
r_cons_flush();
|
||||
ch = r_cons_readchar();
|
||||
ch = r_cons_arrow_to_hjkl(ch); // get ESC+char, return 'hjkl' char
|
||||
r_cons_flush ();
|
||||
ch = r_cons_readchar ();
|
||||
ch = r_cons_arrow_to_hjkl (ch); // get ESC+char, return 'hjkl' char
|
||||
|
||||
switch(ch) {
|
||||
switch (ch) {
|
||||
case 'j':
|
||||
option++;
|
||||
break;
|
||||
|
|
|
@ -100,12 +100,13 @@ R_API ut64 r_debug_reg_get(struct r_debug_t *dbg, const char *name) {
|
|||
RRegItem *ri = NULL;
|
||||
ut64 ret = 0LL;
|
||||
int role = r_reg_get_name_idx (name);
|
||||
const char *pname = name;
|
||||
if (!dbg || !dbg->reg)
|
||||
return R_FALSE;
|
||||
if (role != -1) {
|
||||
name = r_reg_get_name (dbg->reg, role);
|
||||
if (name == NULL || *name == '\0') {
|
||||
eprintf ("Cannot resolve name for register role '%s'.\n", name);
|
||||
eprintf ("No debug register profile defined for '%s'.\n", pname);
|
||||
return 0LL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,6 +224,7 @@ R_API void r_base64_encode(ut8 *bout, const ut8 *bin, int len);
|
|||
R_API int r_base64_decode(ut8 *bout, const ut8 *bin, int len);
|
||||
/* strings */
|
||||
#define r_str_write(x,y) write (x, y, strlen(y))
|
||||
R_API void r_str_cpy(char *dst, const char *src);
|
||||
R_API int r_str_bits (char *strout, const ut8 *buf, int len, const char *bitz);
|
||||
R_API int r_str_rwx(const char *str);
|
||||
R_API void r_str_subchr (char *s, int a, int b);
|
||||
|
|
|
@ -64,7 +64,7 @@ static int r_line_readchar() {
|
|||
R_API int r_line_hist_add(const char *line) {
|
||||
if (I.history.top>=I.history.size)
|
||||
I.history.top = I.history.index = 0; // workaround
|
||||
if (*line) { // && I.history.index < I.history.size) {
|
||||
if (line && *line) { // && I.history.index < I.history.size) {
|
||||
I.history.data[I.history.top++] = strdup (line);
|
||||
I.history.index = I.history.top;
|
||||
return R_TRUE;
|
||||
|
|
|
@ -312,11 +312,11 @@ R_API char *r_str_chop(char *str) {
|
|||
while (*str && iswhitechar (*str))
|
||||
str = str + 1;
|
||||
|
||||
len = strlen(str);
|
||||
len = strlen (str);
|
||||
|
||||
if (len>0)
|
||||
for (ptr = str+len-1;ptr!=str;ptr = ptr - 1) {
|
||||
if (iswhitechar (ptr[0]))
|
||||
for (ptr = str+len-1; ptr!=str; ptr--) {
|
||||
if (iswhitechar (*ptr))
|
||||
*ptr = '\0';
|
||||
else break;
|
||||
}
|
||||
|
@ -325,25 +325,23 @@ R_API char *r_str_chop(char *str) {
|
|||
|
||||
R_API char *r_str_trim_head(char *str) {
|
||||
if (str)
|
||||
while (*str && iswhitechar(*str))
|
||||
while (*str && iswhitechar (*str))
|
||||
str++;
|
||||
return str;
|
||||
}
|
||||
|
||||
R_API char *r_str_trim_tail(char *str) {
|
||||
char *ptr = str;
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
ptr += strlen(str)-1;
|
||||
while ((ptr > str) && iswhitechar(*ptr)) {
|
||||
if (str == NULL) return NULL;
|
||||
if (!*str) return str;
|
||||
ptr += strlen (str);
|
||||
for (ptr--; (ptr > str) && iswhitechar (*ptr); ptr--)
|
||||
*ptr = '\0';
|
||||
ptr--;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
R_API char *r_str_trim_head_tail(char *str) {
|
||||
return r_str_trim_tail(r_str_trim_head(str));
|
||||
return r_str_trim_tail (r_str_trim_head (str));
|
||||
}
|
||||
|
||||
R_API char *r_str_trim(char *str) {
|
||||
|
@ -351,13 +349,20 @@ R_API char *r_str_trim(char *str) {
|
|||
char *ptr;
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
for (ptr=str, i=0;str[i];i++)
|
||||
for (ptr=str, i=0;str[i]; i++)
|
||||
if (!iswhitechar (str[i]))
|
||||
*ptr++ = str[i];
|
||||
*ptr='\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
R_API void r_str_cpy(char *dst, const char *src) {
|
||||
int i;
|
||||
for (i=0; src[i]; i++)
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
||||
/* memccmp("foo.bar", "foo.cow, '.') == 0 */
|
||||
R_API int r_str_ccmp(const char *dst, const char *src, int ch) {
|
||||
int i;
|
||||
|
@ -697,6 +702,7 @@ R_API int r_str_glob (const char *str, const char *glob) {
|
|||
}
|
||||
}
|
||||
|
||||
// XXX: remove this limit .. use realloc
|
||||
#define MAXARG 128
|
||||
R_API char **r_str_argv(const char *_str, int *_argc) {
|
||||
int argc = 0;
|
||||
|
|
Loading…
Reference in New Issue