8 void ct_print_header(const char *content_type, const char *charset)
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);
17 const gchar *ct_get_path_info(void)
19 return g_getenv("PATH_INFO") ?: "";
22 const gchar *ct_get_query_string(void)
24 return g_getenv("QUERY_STRING") ?: "";
27 const GHashTable *ct_get_query(void)
29 const gchar *query_string = g_getenv("QUERY_STRING");
30 GHashTable *query = g_hash_table_new(g_str_hash, g_str_equal);
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
46 static int printf_markup(FILE *stream,
47 const struct printf_info *info,
48 const void *const *args)
51 const char *str = *(const char **)args[0];
52 for (int i = 0; str[i]; i++)
54 case '"': len += fputs("'", stream); break;
55 case '\'': len += fputs(""", stream); break;
56 case '&': len += fputs("&", stream); break;
57 case '<': len += fputs("<", stream); break;
58 case '>': len += fputs(">", stream); break;
59 default: len += fputc(str[i], stream); break;
64 static int printf_markup_arginfo(const struct printf_info *info,
65 size_t n, int *argtypes, int *size)
67 argtypes[0] = PA_STRING;
73 register_printf_specifier('M', printf_markup, printf_markup_arginfo);
80 printf("%M\n", "<Hello, World>");
81 printf("%M\n", "<Hello, World>");
82 printf("%M\n", "<Hello, World>");