Browse Source

Mapping support

master
Denis Tereshkin 7 months ago
parent
commit
dbca0f12e1
  1. 79
      src/ftracetool.c

79
src/ftracetool.c

@ -17,6 +17,71 @@
#define CLEANUP(f) __attribute__((cleanup(f))) #define CLEANUP(f) __attribute__((cleanup(f)))
struct ftt_mapping
{
char *key;
char *value;
struct ftt_mapping *next;
};
static struct ftt_mapping *gs_mappings;
static struct ftt_mapping *parse_mapping(const char *const raw_str)
{
struct ftt_mapping *mapping = NULL;
char *const s = strchr(raw_str, '=');
if (s)
{
const size_t len = strlen(raw_str);
const size_t key_len = s - raw_str + 1; // including 0-terminator
const size_t value_len = len - key_len + 1;
if (key_len == 0 || value_len == 0)
{
return NULL;
}
mapping = calloc(1, sizeof(*mapping));
if (!mapping)
{
return NULL;
}
mapping->key = calloc(key_len, sizeof(char));
mapping->value = calloc(value_len, sizeof(char));
if (!mapping->key || !mapping->value)
{
free(mapping->key);
free(mapping->value);
free(mapping);
return NULL;
}
memcpy(mapping->key, raw_str, key_len - 1);
memcpy(mapping->value, s + 1, value_len - 1);
}
return mapping;
}
static int embed_mappings(sexp ctx)
{
sexp_gc_var2(s_mapping, mapping_name);
sexp_gc_preserve2(ctx, mapping_name, s_mapping);
mapping_name = sexp_intern(ctx, "*ftt-mappings*", -1);
s_mapping = SEXP_NULL;
for (struct ftt_mapping const *mapping = gs_mappings; mapping;
mapping = mapping->next)
{
sexp_gc_var3(key, value, cell);
sexp_gc_preserve3(ctx, key, value, cell);
key = sexp_c_string(ctx, mapping->key, -1);
value = sexp_c_string(ctx, mapping->value, -1);
cell = sexp_cons(ctx, key, value);
s_mapping = sexp_cons(ctx, cell, s_mapping);
sexp_gc_release3(ctx);
}
sexp_env_define(ctx, sexp_context_env(ctx), mapping_name, s_mapping);
sexp_gc_release2(ctx);
}
static void show_version() static void show_version()
{ {
printf("ftracetool v%s\n", VERSION_STRING); printf("ftracetool v%s\n", VERSION_STRING);
@ -25,6 +90,7 @@ static void show_version()
static void show_usage() static void show_usage()
{ {
printf("ftracetool v%s\n \ printf("ftracetool v%s\n \
-m key=value Set mapping\n \
-e Execute script\n \ -e Execute script\n \
-s Show symbols in elf file\n \ -s Show symbols in elf file\n \
-v Show version\n \ -v Show version\n \
@ -248,6 +314,7 @@ static int do_execute_script(const char *const filename)
ctx = sexp_make_eval_context(NULL, NULL, NULL, 0, 0); ctx = sexp_make_eval_context(NULL, NULL, NULL, 0, 0);
sexp_load_standard_env(ctx, NULL, SEXP_SEVEN); sexp_load_standard_env(ctx, NULL, SEXP_SEVEN);
sexp_load_standard_ports(ctx, NULL, stdin, stdout, stderr, 1); sexp_load_standard_ports(ctx, NULL, stdin, stdout, stderr, 1);
embed_mappings(ctx);
sexp_gc_var1(filename_obj); sexp_gc_var1(filename_obj);
@ -279,7 +346,7 @@ int main(int argc, char **argv)
char filename[NAME_MAX] = {}; char filename[NAME_MAX] = {};
bool execute_script = false; bool execute_script = false;
bool show_symbols_in_file = false; bool show_symbols_in_file = false;
while ((opt = getopt(argc, argv, "vhs:e:")) != -1) while ((opt = getopt(argc, argv, "vhs:e:m:")) != -1)
{ {
switch (opt) switch (opt)
{ {
@ -305,6 +372,16 @@ int main(int argc, char **argv)
show_symbols_in_file = true; show_symbols_in_file = true;
break; break;
} }
case 'm':
{
struct ftt_mapping *const mapping = parse_mapping(optarg);
if (mapping)
{
mapping->next = gs_mappings;
gs_mappings = mapping;
}
break;
}
default: default:
{ {
show_usage(); show_usage();

Loading…
Cancel
Save