aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blogc/funcvars.c47
-rw-r--r--src/blogc/funcvars.h19
-rw-r--r--src/blogc/renderer.c12
-rw-r--r--src/blogc/rusage.c87
-rw-r--r--src/blogc/rusage.h21
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 */