aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2024-07-06 09:49:51 -0400
committerGitHub <noreply@github.com>2024-07-06 09:49:51 -0400
commit8ce824ac4b2f526331093a7150e643700efd4d20 (patch)
tree99e27dee24e82d78941ded4c510e1bac57c3f015 /docs
parentabe87056faa6ed02aff3bbf77c1fd78b713a0864 (diff)
downloadstasis-8ce824ac4b2f526331093a7150e643700efd4d20.tar.gz
Add github.c and github.h (#9)
* Add github.c and github.h * Implements get_github_release_notes() * Remove unused variables * Fix circular dependency on tplfunc_frame * Remove predeclaration of tplfunc_frame * tpl_register_func accepts pointer to void instead * tpl_register_func sets maximum number of arguments * Frame is generated within tpl_register_func * Improve template function error handling and return/output management * Remove redundant extern statement * Include github.h and template_func_proto.h in core.h * Expose get_github_release_notes_tplfunc_entrypoint function to template engine * Add template_func_proto.c and template_func_proto.h * Replace free() with guard variant * Fix test_template::test_tpl_register_func * Fix tests * Fix tests * cmd should be at least PATH_MAX in size. * Magic number caused failure to install conda with a long installation path * Implement get_github_release_notes_auto function that bases release note data off test contexts * Disable overwriting releases by default * Add automatic release note generation function call to release_notes.md.in * Fix test_tpl_register_func() * Add enough space for tar command plus a path * Fix circular include * Github functions do not require access to core.h anyway * Add comments to union * Update README to mention template function availability * Add EnvCtl structure * Add runtime checks to avoid running all the way to the end only to be met with a configuration error. * Rename GITHUB to GH * Development docs pre-rough-draft
Diffstat (limited to 'docs')
-rw-r--r--docs/Doxyfile2
-rw-r--r--docs/devel.md148
2 files changed, 149 insertions, 1 deletions
diff --git a/docs/Doxyfile b/docs/Doxyfile
index 92fcec2..3964a1e 100644
--- a/docs/Doxyfile
+++ b/docs/Doxyfile
@@ -124,7 +124,7 @@ WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
-INPUT = ../README.md ../src ../include
+INPUT = devel.md ../README.md ../src ../include
INPUT_ENCODING = UTF-8
INPUT_FILE_ENCODING =
FILE_PATTERNS = *.c \
diff --git a/docs/devel.md b/docs/devel.md
new file mode 100644
index 0000000..a288ef5
--- /dev/null
+++ b/docs/devel.md
@@ -0,0 +1,148 @@
+# Developing
+
+# Using the tpl_* functions
+
+```c
+#include <stdio.h> // for fprintf, free, puts
+#include <stdlib.h> // for strdup
+#include "template.h" // for tpl_free, tpl_register, tpl_render
+
+int main(int argc, char *argv[]) {
+ char *value = strdup("the value");
+ tpl_register("my_data", &value);
+ char *rendered = tpl_render("I am showing you {{ my_data }}.");
+ if (rendered) {
+ puts(rendered);
+ free(rendered);
+ } else {
+ fprintf()
+ }
+ tpl_free();
+}
+```
+
+`tpl_register` accepts an address to a heap-allocated pointer of type `char`. One cannot pass the address of a stack-allocated character string, because chances are reasonably high that your C compiler detect this condition and throw an _incompatible pointer_ error. You may, however, register a pointer to a string that has been allocated on the stack (see example).
+
+```c
+// Invalid (stack)
+char value[255];
+
+// Invalid (stack)
+char value[] = "the value";
+
+// Valid (pointer to stack)
+char value_s[] = "the value";
+char *value = value_s;
+
+// Valid (heap)
+char *value = calloc(255, sizeof(*value));
+strcpy(value, "the value");
+
+// Valid (heap)
+char *value = strdup("the value");
+```
+
+The `tpl_render` function parses an input string and replaces any references encapsulated by double curly braces (`{{}}`) with the _current_ value of a registered template variable. Empty references and undefined variables are ignored, however whitespace surrounding the reference will be preserved in the result. If an unrecoverable error occurs while rendering this function returns `NULL`.
+
+The following illustrates this effect:
+```c
+char *abc = strdup("ABC");
+tpl_register("abc", &abc);
+char *rendered = tpl_render("{{}} {{ undefined_var }} I know my {{ abc }}'s!");
+// Result: " I know my ABC's!"
+// ^^ whitespace
+free(rendered);
+tpl_free();
+```
+
+One should consider using the `normalize_space` function to remove undesired whitespace from the rendered output.
+
+```c
+#include <stdio.h> // for fprintf, stderr
+#include "str.h" // for normalize_space
+
+// ...
+char *rendered = tpl_render("{{}} {{ undefined_var }} I know my {{ abc }}'s!");
+if (rendered) {
+ // Remove leading, trailing, and repeated whitespace
+ normalize_space(rendered);
+} else {
+ fprintf(stderr, "unable to render input string\n");
+ exit(1);
+}
+free(rendered);
+tpl_free();
+// Result: "I know my ABC's!"
+```
+
+Most calls to `tpl_render` use data read from a file. The examples below should clarify how to achieve this.
+
+Template file: **index.html.in**
+
+```html
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>{{ site_title }}</title>
+ </head>
+ <body>
+ {{ site_body_text }}
+ <br/>
+ {{ site_footer }}
+ </body>
+</html>
+```
+
+- Using the standard library
+
+```c
+#include <stdio.h> // for fgets
+#include <string.h>
+#include <stdlib.h>
+#include "template.h" // for tpl_render
+
+struct Site {
+ char *title;
+ char *body;
+ char *footer;
+} site;
+
+void site_setup_template() {
+ tpl_register("site_title", &site.title);
+ tpl_register("site_body", &site.body);
+ tpl_register("site_footer", &site.footer);
+}
+
+void site_setup_data() {
+ site.title = strdup("My static site");
+ site.body = strdup("This is the body.");
+ site.footer = strdup("Generated with tpl_render()");
+}
+
+int main(int argc, char *argv[]) {
+ char line[BUFSIZ] = {0};
+ char *filename = argv[1];
+ FILE *fp = fopen(filename, "r");
+ if (!fp) {
+ perror(filename);
+ exit(1);
+ }
+
+ while (fgets(line, sizeof(line) - 1, fp) != NULL) {
+ char *rendered = tpl_render(line);
+ if (rendered) {
+ normalize_space(rendered);
+ printf("%s", rendered);
+ }
+ }
+ fclose(fp);
+}
+```
+
+- Using file_readlines
+
+```c
+
+#include "util.h"
+```
+