radare2/libr/lang/p/vala.c
2016-05-31 10:39:34 +02:00

103 lines
2.7 KiB
C

/* radare - LGPL - Copyright 2011-2016 pancake */
/* vala extension for libr (radare2) */
// TODO: add cache directory (~/.r2/cache)
#include "r_lib.h"
#include "r_core.h"
#include "r_lang.h"
static int lang_vala_file(RLang *lang, const char *file) {
void *lib;
char *p, name[512], buf[512];
char *vapidir, *srcdir, *libname;
if (strlen (file)>500)
return false;
if (!strstr (file, ".vala"))
sprintf (name, "%s.vala", file);
else strcpy (name, file);
if (!r_file_exists (name)) {
eprintf ("file not found (%s)\n", name);
return false;
}
srcdir = strdup (file);
p = (char*)r_str_lchr (srcdir, '/');
if (p) {
*p = 0;
libname = strdup (p+1);
if (*file!='/') {
strcpy (srcdir, ".");
}
} else {
libname = strdup (file);
strcpy (srcdir, ".");
}
r_sys_setenv ("PKG_CONFIG_PATH", R2_LIBDIR"/pkgconfig");
vapidir = r_sys_getenv ("VAPIDIR");
if (vapidir) {
if (*vapidir) {
snprintf (buf, sizeof (buf)-1, "valac -d %s --vapidir=%s --pkg r_core -C %s",
srcdir, vapidir, name);
}
free (vapidir);
} else snprintf (buf, sizeof(buf)-1, "valac -d %s --pkg r_core -C %s", srcdir, name);
free (srcdir);
if (r_sandbox_system (buf, 1) != 0) {
free (libname);
return false;
}
p = strstr (name, ".vala"); if (p) *p=0;
p = strstr (name, ".gs"); if (p) *p=0;
// TODO: use CC environ if possible
snprintf (buf, sizeof (buf), "gcc -fPIC -shared %s.c -o lib%s."R_LIB_EXT
" $(pkg-config --cflags --libs r_core gobject-2.0)", name, libname);
if (r_sandbox_system (buf, 1) != 0) {
free (libname);
return false;
}
snprintf (buf, sizeof (buf), "./lib%s."R_LIB_EXT, libname);
free (libname);
lib = r_lib_dl_open (buf);
if (lib!= NULL) {
void (*fcn)(RCore *);
fcn = r_lib_dl_sym (lib, "entry");
if (fcn) fcn (lang->user);
else eprintf ("Cannot find 'entry' symbol in library\n");
r_lib_dl_close (lib);
} else eprintf ("Cannot open library\n");
r_file_rm (buf); // remove lib
sprintf (buf, "%s.c", name); // remove .c
r_file_rm (buf);
return 0;
}
static int lang_vala_init(void *user) {
// TODO: check if "valac" is found in path
return true;
}
static int lang_vala_run(RLang *lang, const char *code, int len) {
FILE *fd = fopen (".tmp.vala", "w");
if (fd) {
fputs ("using Radare;\n\npublic static void entry(RCore core) {\n", fd);
fputs (code, fd);
fputs (";\n}\n", fd);
fclose (fd);
lang_vala_file (lang, ".tmp.vala");
r_file_rm (".tmp.vala");
} else eprintf ("Cannot open .tmp.vala\n");
return true;
}
static struct r_lang_plugin_t r_lang_plugin_vala = {
.name = "vala",
.ext = "vala",
.license = "LGPL",
.desc = "Vala language extension",
.run = lang_vala_run,
.init = (void*)lang_vala_init,
.run_file = (void*)lang_vala_file,
};