diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/blogc/funcvars.c | 47 | ||||
-rw-r--r-- | src/blogc/funcvars.h | 19 | ||||
-rw-r--r-- | src/blogc/renderer.c | 12 | ||||
-rw-r--r-- | src/blogc/rusage.c | 87 | ||||
-rw-r--r-- | src/blogc/rusage.h | 21 |
5 files changed, 183 insertions, 3 deletions
diff --git a/src/blogc/funcvars.c b/src/blogc/funcvars.c new file mode 100644 index 0000000..a3af274 --- /dev/null +++ b/src/blogc/funcvars.c @@ -0,0 +1,47 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + +#include "funcvars.h" +#include "rusage.h" +#include "../common/utils.h" + + +static const struct func_map { + const char *variable; + const blogc_funcvars_func_t func; +} funcs[] = { + {"BLOGC_RUSAGE_CPU_TIME", blogc_rusage_cpu_time}, + {"BLOGC_RUSAGE_MEMORY", blogc_rusage_memory}, + {NULL, NULL}, +}; + + +char* +blogc_funcvars_lookup(const char *name, bc_trie_t *global) +{ + // protect against evaluating the same function twice in the same global + // context + if (NULL != bc_trie_lookup(global, name)) + return NULL; + + for (size_t i = 0; funcs[i].variable != NULL; i++) { + if (0 == strcmp(name, funcs[i].variable)) { + char *val = funcs[i].func(); + if (val == NULL) + return NULL; + bc_trie_insert(global, name, bc_strdup(val)); + return val; + } + } + + return NULL; +} diff --git a/src/blogc/funcvars.h b/src/blogc/funcvars.h new file mode 100644 index 0000000..d46266f --- /dev/null +++ b/src/blogc/funcvars.h @@ -0,0 +1,19 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifndef ___FUNCVARS_H +#define ___FUNCVARS_H + +#include <stdbool.h> +#include "../common/utils.h" + +typedef char* (*blogc_funcvars_func_t) (void); + +char* blogc_funcvars_lookup(const char *name, bc_trie_t *global); + +#endif /* ___FUNCVARS_H */ diff --git a/src/blogc/renderer.c b/src/blogc/renderer.c index 6a591ec..2326e09 100644 --- a/src/blogc/renderer.c +++ b/src/blogc/renderer.c @@ -12,6 +12,7 @@ #include <stdlib.h> #include <string.h> #include "datetime-parser.h" +#include "funcvars.h" #include "template-parser.h" #include "renderer.h" #include "../common/error.h" @@ -101,10 +102,15 @@ blogc_format_variable(const char *name, bc_trie_t *global, bc_trie_t *local, } if ((0 == strcmp(var, "FOREACH_ITEM")) && - (foreach_var != NULL && foreach_var->data != NULL)) + (foreach_var != NULL && foreach_var->data != NULL)) { value = foreach_var->data; - else - value = blogc_get_variable(var, global, local); + } + else { + value = blogc_funcvars_lookup(var, global); + if (value == NULL) { + value = blogc_get_variable(var, global, local); + } + } if (value == NULL) { free(var); diff --git a/src/blogc/rusage.c b/src/blogc/rusage.c new file mode 100644 index 0000000..b04938e --- /dev/null +++ b/src/blogc/rusage.c @@ -0,0 +1,87 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#ifdef HAVE_SYS_TIME_H +#include <sys/time.h> +#endif /* HAVE_SYS_TIME_H */ + +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif /* HAVE_SYS_RESOURCE_H */ + +#include "../common/utils.h" +#include "rusage.h" + +// FIXME: optimize to use a single syscall for both cpu time and memory? + + +#include <stdio.h> +long long +blogc_rusage_get_cpu_time(void) +{ + struct rusage usage; + if (0 != getrusage(RUSAGE_SELF, &usage)) + return 0; + return ( + (usage.ru_utime.tv_sec * 1000000) + usage.ru_utime.tv_usec + + (usage.ru_stime.tv_sec * 1000000) + usage.ru_stime.tv_usec); +} + + +char* +blogc_rusage_format_cpu_time(long long time) +{ + if (time > 1000000) + return bc_strdup_printf("%.3s", ((float) time) / 1000000.0); + + // this is a special case: some systems may report the cpu time rounded up to the + // milisecond. it is useless to show ".000" in this case. + if (time > 1000) + return bc_strdup_printf("%.*fms", time % 1000 ? 3 : 0, ((float) time) / 1000.0); + + return bc_strdup_printf("%dus", time); +} + + +char* +blogc_rusage_cpu_time(void) +{ + return blogc_rusage_format_cpu_time(blogc_rusage_get_cpu_time()); +} + + +long +blogc_rusage_get_memory(void) +{ + struct rusage usage; + if (0 != getrusage(RUSAGE_SELF, &usage)) + return 0; + return usage.ru_maxrss; +} + + +char* +blogc_rusage_format_memory(long mem) +{ + if (mem > 1048576) + return bc_strdup_printf("%.3fGB", ((float) mem) / 1048576.0); + if (mem > 1024) + return bc_strdup_printf("%.3fMB", ((float) mem) / 1024.0); + return bc_strdup_printf("%dKB", mem); +} + + +char* +blogc_rusage_memory(void) +{ + return blogc_rusage_format_memory(blogc_rusage_get_memory()); +} diff --git a/src/blogc/rusage.h b/src/blogc/rusage.h new file mode 100644 index 0000000..cfdccbe --- /dev/null +++ b/src/blogc/rusage.h @@ -0,0 +1,21 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2019 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifndef ___RUSAGE_H +#define ___RUSAGE_H + +long long blogc_rusage_get_cpu_time(void); // in microseconds +long blogc_rusage_get_memory(void); // in kilobytes + +char* blogc_rusage_format_cpu_time(long long time); +char* blogc_rusage_format_memory(long mem); + +char* blogc_rusage_cpu_time(void); +char* blogc_rusage_memory(void); + +#endif /* ___RUSAGE_H */ |