]> Pileus Git - ~andy/ct/blob - lib.c
Update mkgallery script
[~andy/ct] / lib.c
1 #define _GNU_SOURCE
2 #include <glib.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <printf.h>
6
7 /* Misc */
8 void ct_print_header(const char *content_type, const char *charset)
9 {
10         if (!content_type) content_type = "text/html";
11         if (!charset)      charset      = "UTF-8";
12         printf("Content-Type: %s; charset=%s\n\n",
13                         content_type, charset);
14 }
15
16 /* Environment */
17 const gchar *ct_get_path_info(void)
18 {
19         return g_getenv("PATH_INFO") ?: "";
20 }
21
22 const gchar *ct_get_query_string(void)
23 {
24         return g_getenv("QUERY_STRING") ?: "";
25 }
26
27 const GHashTable *ct_get_query(void)
28 {
29         const gchar *query_string = g_getenv("QUERY_STRING");
30         GHashTable *query = g_hash_table_new(g_str_hash, g_str_equal);
31         if (query_string) {
32                 gchar **vars = g_strsplit(query_string, "&", -1);
33                 for (int i = 0; vars[i]; i++) {
34                         gchar **parts = g_strsplit(vars[i], "=", 2);
35                         gchar *lhs = parts[0]             ? parts[0] : "";
36                         gchar *rhs = parts[0] && parts[1] ? parts[1] : "";
37                         g_hash_table_insert(query, lhs, rhs);
38                         g_free(parts); // keep lhs/rhs
39                 }
40                 g_strfreev(vars);
41         }
42         return query;
43 }
44
45 /* Markup escaping */
46 static int printf_markup(FILE *stream,
47                 const struct printf_info *info,
48                 const void *const *args)
49 {
50         int len = 0;
51         const char *str = *(const char **)args[0];
52         for (int i = 0; str[i]; i++)
53                 switch (str[i]) {
54                 case '"':  len += fputs("&#39;",  stream); break;
55                 case '\'': len += fputs("&quot;", stream); break;
56                 case '&':  len += fputs("&amp;",  stream); break;
57                 case '<':  len += fputs("&lt;",   stream); break;
58                 case '>':  len += fputs("&gt;",   stream); break;
59                 default:   len += fputc(str[i],   stream); break;
60                 }
61         return len;
62 }
63
64 static int printf_markup_arginfo(const struct printf_info *info,
65                 size_t n, int *argtypes, int *size)
66 {
67         argtypes[0] = PA_STRING;
68         return 1;
69 }
70
71 void ct_use_escape()
72 {
73         register_printf_specifier('M', printf_markup, printf_markup_arginfo);
74 }
75
76 #ifdef TEST
77 int main(void)
78 {
79         ct_use_escape();
80         printf("%M\n", "<Hello, World>");
81         printf("%M\n", "<Hello, World>");
82         printf("%M\n", "<Hello, World>");
83         return 0;
84 }
85 #endif