From 65da25d4c003170cb080b8ba1ec296949f295e16 Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 14 Aug 2009 01:44:12 +0000 Subject: [PATCH] * Implement STATIC PLUGIN support for r_parse - Use the new 'asm-like' build system for r_parse plugins - Added new callback to 'assemble' parseable expressions into compilable asm code - Refactorize and remove warnings in parse_mreplace * Added r_str_char_count() in r_util * Some fixups in the fastcall code in r_asm --HG-- rename : libr/parse/p/mreplace/mmemory.c => libr/parse/p/parse_mreplace/mmemory.c rename : libr/parse/p/mreplace/mmemory.h => libr/parse/p/parse_mreplace/mmemory.h rename : libr/parse/p/mreplace/mreplace.c => libr/parse/p/parse_mreplace/mreplace.c rename : libr/parse/p/mreplace/mreplace.h => libr/parse/p/parse_mreplace/mreplace.h --- libr/asm/p/asm_mips.c | 4 +- libr/asm/p/asm_x86.c | 2 +- libr/asm/p/asm_x86_bea.c | 9 ++-- libr/asm/p/asm_x86_olly.c | 2 +- libr/asm/p/fastcall_x86.h | 2 +- libr/asm/t/Makefile | 2 - libr/config.h | 6 +++ libr/config.mk | 1 + libr/include/r_parse.h | 6 +++ libr/include/r_util.h | 1 + libr/parse/Makefile | 17 +++++- libr/parse/p/Makefile | 54 +++++++++++++------ libr/parse/p/dummy.mk | 10 ++++ libr/parse/p/mreplace.mk | 10 ++++ libr/parse/p/parse_dummy.c | 6 ++- libr/parse/p/parse_mreplace.c | 9 ++-- .../p/{mreplace => parse_mreplace}/mmemory.c | 1 - .../p/{mreplace => parse_mreplace}/mmemory.h | 0 .../p/{mreplace => parse_mreplace}/mreplace.c | 17 +++--- .../p/{mreplace => parse_mreplace}/mreplace.h | 0 libr/parse/p/parse_x86_pseudo.c | 13 ++++- libr/parse/p/x86_pseudo.mk | 10 ++++ libr/parse/parse.c | 7 +++ libr/parse/t/Makefile | 6 +++ libr/parse/t/parse.c | 12 +++++ libr/util/str.c | 9 ++++ 26 files changed, 170 insertions(+), 46 deletions(-) create mode 100644 libr/parse/p/dummy.mk create mode 100644 libr/parse/p/mreplace.mk rename libr/parse/p/{mreplace => parse_mreplace}/mmemory.c (99%) rename libr/parse/p/{mreplace => parse_mreplace}/mmemory.h (100%) rename libr/parse/p/{mreplace => parse_mreplace}/mreplace.c (95%) rename libr/parse/p/{mreplace => parse_mreplace}/mreplace.h (100%) create mode 100644 libr/parse/p/x86_pseudo.mk create mode 100644 libr/parse/t/Makefile create mode 100644 libr/parse/t/parse.c diff --git a/libr/asm/p/asm_mips.c b/libr/asm/p/asm_mips.c index feb0d9f391..b9cc604acd 100644 --- a/libr/asm/p/asm_mips.c +++ b/libr/asm/p/asm_mips.c @@ -12,6 +12,7 @@ #include "dis-asm.h" #include "opcode/mips.h" +#include "fastcall_mips.h" static int mips_mode = 0; static unsigned long Offset = 0; @@ -99,7 +100,8 @@ struct r_asm_handle_t r_asm_plugin_mips = { .init = NULL, .fini = NULL, .disassemble = &disassemble, - .assemble = NULL + .assemble = NULL, + .fastcall = fastcall }; #ifndef CORELIB diff --git a/libr/asm/p/asm_x86.c b/libr/asm/p/asm_x86.c index e71977b280..2aeaa7a985 100644 --- a/libr/asm/p/asm_x86.c +++ b/libr/asm/p/asm_x86.c @@ -42,7 +42,7 @@ struct r_asm_handle_t r_asm_plugin_x86 = { .fini = NULL, .disassemble = &disassemble, .assemble = NULL, - .fastcall = &fastcall, + .fastcall = fastcall, }; #ifndef CORELIB diff --git a/libr/asm/p/asm_x86_bea.c b/libr/asm/p/asm_x86_bea.c index 9e7626bac4..a689931533 100644 --- a/libr/asm/p/asm_x86_bea.c +++ b/libr/asm/p/asm_x86_bea.c @@ -10,6 +10,8 @@ #include "x86/bea/BeaEngine.h" +#include "fastcall_x86.h" + static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len) { @@ -22,8 +24,7 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut6 disasm_obj.SecurityBlock = len; if (a->syntax == R_ASM_SYN_ATT) disasm_obj.Options = 0x400; - else - disasm_obj.Options = 0; + else disasm_obj.Options = 0; aop->inst_len = Disasm(&disasm_obj); aop->disasm_obj = &disasm_obj; @@ -33,8 +34,6 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut6 return aop->inst_len; } -#include "fastcall_x86.h" - struct r_asm_handle_t r_asm_plugin_x86_bea = { .name = "asm_x86_bea", .desc = "X86 disassembly plugin (bea engine)", @@ -44,7 +43,7 @@ struct r_asm_handle_t r_asm_plugin_x86_bea = { .fini = NULL, .disassemble = &disassemble, .assemble = NULL, - .fastcall = &fastcall, + .fastcall = fastcall, }; #ifndef CORELIB diff --git a/libr/asm/p/asm_x86_olly.c b/libr/asm/p/asm_x86_olly.c index 2d12b50d88..abe83e610c 100644 --- a/libr/asm/p/asm_x86_olly.c +++ b/libr/asm/p/asm_x86_olly.c @@ -62,7 +62,7 @@ struct r_asm_handle_t r_asm_plugin_x86_olly = { .fini = NULL, .disassemble = &disassemble, .assemble = &assemble, - .fastcall = &fastcall, + .fastcall = fastcall, }; #ifndef CORELIB diff --git a/libr/asm/p/fastcall_x86.h b/libr/asm/p/fastcall_x86.h index e209b302ef..1fb91de495 100644 --- a/libr/asm/p/fastcall_x86.h +++ b/libr/asm/p/fastcall_x86.h @@ -1,4 +1,4 @@ -static struct r_asm_fastcall_t fastcall[R_ASM_FASTCALL_ARGS] = { +static struct r_asm_fastcall_t fastcall [R_ASM_FASTCALL_ARGS] = { { NULL }, { "eax", NULL }, { "eax", "ebx", NULL }, diff --git a/libr/asm/t/Makefile b/libr/asm/t/Makefile index cf611fc74b..8d6e9bb348 100644 --- a/libr/asm/t/Makefile +++ b/libr/asm/t/Makefile @@ -3,8 +3,6 @@ BIN=rasm2 BINDEPS=r_util r_lib r_asm r_print r_cons LIBS+=-ldl -include ../../rules.mk - all: ${BIN} fastcall fastcall: fastcall.o diff --git a/libr/config.h b/libr/config.h index 930ff92ef3..11e90d649d 100644 --- a/libr/config.h +++ b/libr/config.h @@ -16,6 +16,12 @@ &r_asm_plugin_mips, \ 0 +#define R_PARSE_STATIC_PLUGINS \ + &r_parse_plugin_dummy, \ + &r_parse_plugin_x86_pseudo, \ + &r_parse_plugin_mreplace, \ + 0 + #define R_BIN_STATIC_PLUGINS \ &r_bin_plugin_elf , \ &r_bin_plugin_elf64 , \ diff --git a/libr/config.mk b/libr/config.mk index 23a190e500..8f4554425d 100644 --- a/libr/config.mk +++ b/libr/config.mk @@ -10,6 +10,7 @@ USE_RIO=1 STATIC_DEBUG=0 RUNTIME_DEBUG=1 STATIC_ASM_PLUGINS=p/x86olly.mk p/x86nasm.mk p/mips.mk p/java.mk +STATIC_PARSE_PLUGINS=p/dummy.mk p/x86_pseudo.mk p/mreplace.mk STATIC_BIN_PLUGINS=p/elf.mk p/elf64.mk p/pe.mk p/pe64.mk p/java.mk p/dummy.mk STATIC_BP_PLUGINS=p/x86.mk STATIC_BININFO_PLUGINS=p/addr2line.mk diff --git a/libr/include/r_parse.h b/libr/include/r_parse.h index 61852fefef..6dc950693f 100644 --- a/libr/include/r_parse.h +++ b/libr/include/r_parse.h @@ -21,6 +21,7 @@ struct r_parse_handle_t { int (*init)(void *user); int (*fini)(void *user); int (*parse)(struct r_parse_t *p, void *data, char *str); + int (*assemble)(struct r_parse_t *p, void *data, char *str); struct list_head list; }; @@ -34,4 +35,9 @@ int r_parse_list(struct r_parse_t *p); int r_parse_set(struct r_parse_t *p, const char *name); int r_parse_parse(struct r_parse_t *p, void *data, char *str); +/* plugin pointers */ +extern struct r_parse_handle_t r_parse_plugin_dummy; +extern struct r_parse_handle_t r_parse_plugin_x86_pseudo; +extern struct r_parse_handle_t r_parse_plugin_mreplace; + #endif diff --git a/libr/include/r_util.h b/libr/include/r_util.h index b9d7b8cbc0..3656c01a4a 100644 --- a/libr/include/r_util.h +++ b/libr/include/r_util.h @@ -72,6 +72,7 @@ R_API void r_num_init(struct r_num_t *num); R_API const char *r_str_ansi_chrn(const char *str, int n); R_API int r_str_ansi_len(const char *str); R_API int r_str_word_count(const char *string); +R_API int r_str_char_count(const char *string, char ch); R_API int r_str_word_set0(char *str); R_API char *r_str_word_get0(char *str, int idx); R_API char *r_str_word_get_first(const char *string); diff --git a/libr/parse/Makefile b/libr/parse/Makefile index c57921a898..924475aea6 100644 --- a/libr/parse/Makefile +++ b/libr/parse/Makefile @@ -1,4 +1,19 @@ NAME=r_parse -OBJ=parse.o +DEPS=r_lib + +foo: pre libr_parse.so plugins + +CFLAGS+=-DCORELIB +include ../config.mk +include ${STATIC_PARSE_PLUGINS} +STATIC_OBJS=$(subst ..,p/..,$(subst parse_,p/parse_,$(STATIC_OBJ))) +OBJ=parse.o ${STATIC_OBJS} + + +pre: + @if [ ! -e libr_parse.so ]; then rm -f ${STATIC_OBJS} ; fi + +plugins: + cd p && ${MAKE} all include ../rules.mk diff --git a/libr/parse/p/Makefile b/libr/parse/p/Makefile index 17745deb3b..a12e166d1c 100644 --- a/libr/parse/p/Makefile +++ b/libr/parse/p/Makefile @@ -1,21 +1,41 @@ -CFLAGS=-I../../include -I../arch/ -I../arch/include -Wall -fPIC -shared -Wl,-R.. -CFLAGS_IMP=-I../../include -I../arch/ -I../arch/include -w -fPIC -shared -Wl,-R.. +CFLAGS=-I../../include -Wall -fPIC -shared -Wl,-R.. +# XXX +CFLAGS+=-DLIL_ENDIAN=1 -D__UNIX__ +CFLAGS+=-DCORELIB -all: parse_dummy.so parse_x86_pseudo.so parse_mreplace.so +foo: all + +ALL_TARGETS= +ARCHS=dummy.mk x86_pseudo.mk mreplace.mk +include $(ARCHS) + +all: ${ALL_TARGETS} @true -parse_dummy.so: parse_dummy.o - ${CC} ${CFLAGS} -o parse_dummy.so parse_dummy.o - @#strip -s parse_dummy.so - -parse_x86_pseudo.so: parse_x86_pseudo.o - ${CC} ${CFLAGS} -o parse_x86_pseudo.so parse_x86_pseudo.o - @#strip -s parse_x86_pseudo.so - -parse_mreplace.so: parse_mreplace.o - ${CC} ${CFLAGS_IMP} -o parse_mreplace.so \ - mreplace/mreplace.c mreplace/mmemory.c parse_mreplace.o - @#strip -s parse_mreplace.so - clean: - -rm -f *.so *.o + -rm -f *.so *.o ${STATIC_OBJ} + +.PHONY: all clean foo + + +#CFLAGS=-I../../include -I../arch/ -I../arch/include -Wall -fPIC -shared -Wl,-R.. +#CFLAGS_IMP=-I../../include -I../arch/ -I../arch/include -w -fPIC -shared -Wl,-R.. +# +#all: parse_dummy.so parse_x86_pseudo.so parse_mreplace.so +# @true +# +#parse_dummy.so: parse_dummy.o +# ${CC} ${CFLAGS} -o parse_dummy.so parse_dummy.o +# @#strip -s parse_dummy.so +# +#parse_x86_pseudo.so: parse_x86_pseudo.o +# ${CC} ${CFLAGS} -o parse_x86_pseudo.so parse_x86_pseudo.o +# @#strip -s parse_x86_pseudo.so +# +#parse_mreplace.so: parse_mreplace.o +# ${CC} ${CFLAGS_IMP} -o parse_mreplace.so \ +# mreplace/mreplace.c mreplace/mmemory.c parse_mreplace.o +# @#strip -s parse_mreplace.so +# +#clean: +# -rm -f *.so *.o diff --git a/libr/parse/p/dummy.mk b/libr/parse/p/dummy.mk new file mode 100644 index 0000000000..deb6b41c63 --- /dev/null +++ b/libr/parse/p/dummy.mk @@ -0,0 +1,10 @@ +OBJ_DUMMY+=parse_dummy.o + +TARGET_DUMMY=parse_dummy.so +ALL_TARGETS+=${TARGET_DUMMY} +STATIC_OBJ+=${OBJ_DUMMY} + +${TARGET_DUMMY}: ${OBJ_DUMMY} + ${CC} ${CFLAGS} -o ${TARGET_DUMMY} ${OBJ_DUMMY} + @#strip -s asm_dummy.so + diff --git a/libr/parse/p/mreplace.mk b/libr/parse/p/mreplace.mk new file mode 100644 index 0000000000..5c3dc2da10 --- /dev/null +++ b/libr/parse/p/mreplace.mk @@ -0,0 +1,10 @@ +OBJ_MREPLACE+=parse_mreplace.o parse_mreplace/mreplace.o parse_mreplace/mmemory.o + +TARGET_MREPLACE=parse_mreplace.so +ALL_TARGETS+=${TARGET_MREPLACE} +STATIC_OBJ+=${OBJ_MREPLACE} + +${TARGET_MREPLACE}: ${OBJ_MREPLACE} + ${CC} ${CFLAGS} -o ${TARGET_MREPLACE} ${OBJ_MREPLACE} + @#strip -s asm_dummy.so + diff --git a/libr/parse/p/parse_dummy.c b/libr/parse/p/parse_dummy.c index 22e575d07d..7dd1cbd5b7 100644 --- a/libr/parse/p/parse_dummy.c +++ b/libr/parse/p/parse_dummy.c @@ -12,7 +12,7 @@ static int parse(struct r_parse_t *p, void *data, char *str) return R_FALSE; } -static struct r_parse_handle_t r_parse_plugin_parse_dummy = { +struct r_parse_handle_t r_parse_plugin_dummy = { .name = "parse_dummy", .desc = "dummy parsing plugin", .init = NULL, @@ -20,7 +20,9 @@ static struct r_parse_handle_t r_parse_plugin_parse_dummy = { .parse = &parse, }; +#ifndef CORELIB struct r_lib_struct_t radare_plugin = { .type = R_LIB_TYPE_PARSE, - .data = &r_parse_plugin_parse_dummy + .data = &r_parse_plugin_dummy }; +#endif diff --git a/libr/parse/p/parse_mreplace.c b/libr/parse/p/parse_mreplace.c index f78dd736a9..579e652e71 100644 --- a/libr/parse/p/parse_mreplace.c +++ b/libr/parse/p/parse_mreplace.c @@ -3,7 +3,7 @@ #include #include -#include "mreplace/mreplace.h" +#include "parse_mreplace/mreplace.h" #include #include @@ -27,7 +27,7 @@ static int parse(struct r_parse_t *p, void *data, char *str) return R_TRUE; } -static struct r_parse_handle_t r_parse_plugin_parse_mreplace = { +struct r_parse_handle_t r_parse_plugin_mreplace = { .name = "parse_mreplace", .desc = "mreplace parsing plugin", .init = NULL, @@ -35,7 +35,10 @@ static struct r_parse_handle_t r_parse_plugin_parse_mreplace = { .parse = &parse, }; + +#ifndef CORELIB struct r_lib_struct_t radare_plugin = { .type = R_LIB_TYPE_PARSE, - .data = &r_parse_plugin_parse_mreplace + .data = &r_parse_plugin_mreplace }; +#endif diff --git a/libr/parse/p/mreplace/mmemory.c b/libr/parse/p/parse_mreplace/mmemory.c similarity index 99% rename from libr/parse/p/mreplace/mmemory.c rename to libr/parse/p/parse_mreplace/mmemory.c index 5c00e37baf..a19c96243d 100644 --- a/libr/parse/p/mreplace/mmemory.c +++ b/libr/parse/p/parse_mreplace/mmemory.c @@ -102,7 +102,6 @@ void memCopy(memChunk *dest,memChunk *source){ } void memStrCat(memChunk *dest,char *string){ - long nbytes; memChunk result,*temp; temp = memReserve(dest->size+strlen(string)+1); diff --git a/libr/parse/p/mreplace/mmemory.h b/libr/parse/p/parse_mreplace/mmemory.h similarity index 100% rename from libr/parse/p/mreplace/mmemory.h rename to libr/parse/p/parse_mreplace/mmemory.h diff --git a/libr/parse/p/mreplace/mreplace.c b/libr/parse/p/parse_mreplace/mreplace.c similarity index 95% rename from libr/parse/p/mreplace/mreplace.c rename to libr/parse/p/parse_mreplace/mreplace.c index af26453181..612b720b75 100644 --- a/libr/parse/p/mreplace/mreplace.c +++ b/libr/parse/p/parse_mreplace/mreplace.c @@ -62,15 +62,15 @@ void sreplace(char *s,char *orig,char *rep,char multi,long dsize){ char *mreplace(char *string, char *se,char *rep) { - int status,m,i; - char *s,noMatch=0; + int status,i; + char noMatch=0; regex_t re; size_t nmatch = 16; regmatch_t pm[nmatch]; - char regError[64],*p; + char *p; ulong offset = 0; char field[16]; - char *sData,*res; + char *res; memChunk *search,*temp,*found,*ffound; if(!string) return ""; @@ -92,7 +92,7 @@ char *mreplace(char *string, char *se,char *rep) if(regcomp(&re, search->address, REG_EXTENDED) != 0) if(regcomp(&re, search->address, REG_EXTENDED<<1)) noMatch=1; - if(status = regexec(&re, string, nmatch, pm, 0)) noMatch=1; + if((status = regexec(&re, string, nmatch, pm, 0))) noMatch=1; if(noMatch){ memFree(temp); @@ -104,7 +104,7 @@ char *mreplace(char *string, char *se,char *rep) ffound = memReserve(INPUTLINE_BUFFER_REPLACE_SIZE); while(!status){ offset=strlen(temp->address)-strlen(string); - snprintf(found->address,INPUTLINE_BUFFER_REPLACE_SIZE,"%.*s",pm[0].rm_eo - pm[0].rm_so, &string[pm[0].rm_so],&string[pm[0].rm_so]); + snprintf(found->address,INPUTLINE_BUFFER_REPLACE_SIZE,"%.*s",pm[0].rm_eo - pm[0].rm_so, &string[pm[0].rm_so]);//,&string[pm[0].rm_so]); #if MDEBUG3 printf("------->> found \"%s\" length => %d offset[%d]\n", found->address, @@ -112,7 +112,7 @@ char *mreplace(char *string, char *se,char *rep) #endif sreplace(temp->address+offset,found->address,rep,0,INPUTLINE_BUFFER_REPLACE_SIZE-offset); for(i=1;iaddress,INPUTLINE_BUFFER_REPLACE_SIZE,"%.*s",pm[i].rm_eo - pm[i].rm_so, &string[pm[i].rm_so],&string[pm[i].rm_so]); + snprintf(ffound->address,INPUTLINE_BUFFER_REPLACE_SIZE,"%.*s",pm[i].rm_eo - pm[i].rm_so, &string[pm[i].rm_so]);//,&string[pm[i].rm_so]); snprintf(field,sizeof(field),"\\%d",i); if(strlen(ffound->address)) { sreplace(temp->address,field,ffound->address,1,INPUTLINE_BUFFER_REPLACE_SIZE); @@ -147,11 +147,10 @@ char *mreplace(char *string, char *se,char *rep) } char *treplace(char *data,char *search,char *replace){ - long offset=0,f; char *newline,*p; memChunk *result,*line; - ulong resultAllocSize; + //ulong resultAllocSize; if(!strlen(search)) return data; diff --git a/libr/parse/p/mreplace/mreplace.h b/libr/parse/p/parse_mreplace/mreplace.h similarity index 100% rename from libr/parse/p/mreplace/mreplace.h rename to libr/parse/p/parse_mreplace/mreplace.h diff --git a/libr/parse/p/parse_x86_pseudo.c b/libr/parse/p/parse_x86_pseudo.c index 317d8e6461..6bc780f795 100644 --- a/libr/parse/p/parse_x86_pseudo.c +++ b/libr/parse/p/parse_x86_pseudo.c @@ -123,15 +123,24 @@ static int parse(struct r_parse_t *p, void *data, char *str) return R_TRUE; } -static struct r_parse_handle_t r_parse_plugin_parse_x86_pseudo = { +static int assemble(struct r_parse_t *p, void *data, char *str) +{ + printf("assembling '%s' to generate real asm code\n", str); + return R_TRUE; +} + +struct r_parse_handle_t r_parse_plugin_x86_pseudo = { .name = "parse_x86_pseudo", .desc = "X86 pseudo syntax", .init = NULL, .fini = NULL, .parse = &parse, + .assemble = &assemble, }; +#ifndef CORELIB struct r_lib_struct_t radare_plugin = { .type = R_LIB_TYPE_PARSE, - .data = &r_parse_plugin_parse_x86_pseudo + .data = &r_parse_plugin_x86_pseudo }; +#endif diff --git a/libr/parse/p/x86_pseudo.mk b/libr/parse/p/x86_pseudo.mk new file mode 100644 index 0000000000..e2322a1bea --- /dev/null +++ b/libr/parse/p/x86_pseudo.mk @@ -0,0 +1,10 @@ +OBJ_X86PSEUDO+=parse_x86_pseudo.o + +TARGET_X86PSEUDO=parse_x86_pseudo.so +ALL_TARGETS+=${TARGET_X86PSEUDO} +STATIC_OBJ+=${OBJ_X86PSEUDO} + +${TARGET_X86PSEUDO}: ${OBJ_X86PSEUDO} + ${CC} ${CFLAGS} -o ${TARGET_X86PSEUDO} ${OBJ_X86PSEUDO} + @#strip -s asm_dummy.so + diff --git a/libr/parse/parse.c b/libr/parse/parse.c index 85863103a7..acd1bc14fe 100644 --- a/libr/parse/parse.c +++ b/libr/parse/parse.c @@ -5,6 +5,10 @@ #include #include #include +#include "../config.h" + +static struct r_parse_handle_t *parse_static_plugins[] = + { R_PARSE_STATIC_PLUGINS }; struct r_parse_t *r_parse_new() { @@ -20,8 +24,11 @@ void r_parse_free(struct r_parse_t *p) int r_parse_init(struct r_parse_t *p) { + int i; p->user = NULL; INIT_LIST_HEAD(&p->parsers); + for(i=0;parse_static_plugins[i];i++) + r_parse_add(p, parse_static_plugins[i]); return R_TRUE; } diff --git a/libr/parse/t/Makefile b/libr/parse/t/Makefile new file mode 100644 index 0000000000..c511a84e9f --- /dev/null +++ b/libr/parse/t/Makefile @@ -0,0 +1,6 @@ +OBJ=parse.o +BIN=parse +BINDEPS=r_util r_lib r_parse +LIBS+=-ldl + +include ../../rules.mk diff --git a/libr/parse/t/parse.c b/libr/parse/t/parse.c new file mode 100644 index 0000000000..df00226992 --- /dev/null +++ b/libr/parse/t/parse.c @@ -0,0 +1,12 @@ +#include "r_parse.h" + +int main() +{ + struct r_parse_t *p; + p = r_parse_new(); + printf("List: \n"); + r_parse_list(p); + printf("Using plugin: \n"); + r_parse_set(p, "parse_x86_pseudo"); + return 0; +} diff --git a/libr/util/str.c b/libr/util/str.c index a88f8ce815..7cad0bc401 100644 --- a/libr/util/str.c +++ b/libr/util/str.c @@ -76,6 +76,15 @@ R_API char *r_str_word_get0(char *str, int idx) return ptr; } +R_API int r_str_char_count(const char *string, char ch) +{ + int i, count=0; + for(i=0;string[i];i++) + if (string[i]==ch) + count++; + return count; +} + R_API int r_str_word_count(const char *string) { char *text, *tmp;