From c7f5163c32f3e78df99dca3498eed3b5c8d14000 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Mon, 24 Dec 2012 04:00:26 +0000 Subject: [PATCH] Misc updates --- ct.c | 7 ++++--- ct.h | 17 +++++++++++++++++ example/html.ct | 2 -- lib.c | 40 ++++++++++++++++++++++++++++++++++++++++ makefile | 35 +++++++++++++++++++++++++++++++++++ mkcommon | 6 ------ mkfile | 15 --------------- parse.y | 31 +++++++++++++++---------------- scan.l | 1 + 9 files changed, 112 insertions(+), 42 deletions(-) create mode 100644 ct.h create mode 100644 makefile delete mode 100644 mkcommon delete mode 100644 mkfile diff --git a/ct.c b/ct.c index b9114a9..88becfc 100644 --- a/ct.c +++ b/ct.c @@ -4,12 +4,13 @@ #include "parse.h" -gpointer parse(FILE *input, const char *name, +gpointer parse(const char *name, FILE *input, GList **data, GList **code); int main(int argc, char **argv) { const char *name = "stdin"; + /* Parse arguments */ char *option_output = NULL; GOptionEntry entries[] = { @@ -23,7 +24,7 @@ int main(int argc, char **argv) /* Handle input and output */ FILE *input = stdin; - if (argv[1] && !g_str_equal(input, "-")) { + if (argv[1] && !g_str_equal(argv[1], "-")) { name = argv[1]; input = fopen(argv[1], "r"); } @@ -45,7 +46,7 @@ int main(int argc, char **argv) /* Start compiling */ GList *data = NULL; GList *code = NULL; - parse(input, name, &data, &code); + parse(name, input, &data, &code); data = g_list_reverse(data); code = g_list_reverse(code); diff --git a/ct.h b/ct.h new file mode 100644 index 0000000..9b89350 --- /dev/null +++ b/ct.h @@ -0,0 +1,17 @@ +#ifndef CT_H +#define CT_H + +/* Misc */ +void ct_print_header(const char *content_type, const char *charset); + +/* Environment */ +const gchar *ct_get_query_string(void); + +const gchar *ct_get_path_info(void); + +const GHashTable *ct_get_query(void); + +/* Markup escaping */ +void ct_use_escape(void); + +#endif diff --git a/example/html.ct b/example/html.ct index 7f36cc9..d08df11 100644 --- a/example/html.ct +++ b/example/html.ct @@ -11,8 +11,6 @@ Content-Type: application/xhtml+xml; charset=UTF-8 <% body(); %> - - <%= "%05.2f" %> <% } %> diff --git a/lib.c b/lib.c index 7b46a05..90e698b 100644 --- a/lib.c +++ b/lib.c @@ -1,8 +1,48 @@ #define _GNU_SOURCE +#include #include #include #include +/* Misc */ +void ct_print_header(const char *content_type, const char *charset) +{ + if (!content_type) content_type = "text/html"; + if (!charset) charset = "UTF-8"; + printf("Content-Type: %s; charset=%s\n\n", + content_type, charset); +} + +/* Environment */ +const gchar *ct_get_path_info(void) +{ + return g_getenv("PATH_INFO") ?: ""; +} + +const gchar *ct_get_query_string(void) +{ + return g_getenv("QUERY_STRING") ?: ""; +} + +const GHashTable *ct_get_query(void) +{ + const gchar *query_string = g_getenv("QUERY_STRING"); + GHashTable *query = g_hash_table_new(g_str_hash, g_str_equal); + if (query_string) { + gchar **vars = g_strsplit(query_string, "&", -1); + for (int i = 0; vars[i]; i++) { + gchar **parts = g_strsplit(vars[i], "=", 2); + gchar *lhs = parts[0] ? parts[0] : ""; + gchar *rhs = parts[0] && parts[1] ? parts[1] : ""; + g_hash_table_insert(query, lhs, rhs); + g_free(parts); // keep lhs/rhs + } + g_strfreev(vars); + } + return query; +} + +/* Markup escaping */ static int printf_markup(FILE *stream, const struct printf_info *info, const void *const *args) diff --git a/makefile b/makefile new file mode 100644 index 0000000..edc6978 --- /dev/null +++ b/makefile @@ -0,0 +1,35 @@ +# Settings +PROG = ct +CC = gcc +YACC = bison +LEX = flex + +CFLAGS = -Wall -Werror -g --std=c99 +CPPFLAGS = $(shell pkg-config --cflags glib-2.0) +LDFLAGS = $(shell pkg-config --libs glib-2.0) + +# Targets +default: test + +all: $(PROG) + +test: $(PROG) + ./$(PROG) example/html.ct + +clean: + rm -f $(PROG) *.o *.a parse.h parse.c scan.c + +# Rules +$(PROG): ct.o parse.o scan.o + $(CC) $(CFLAGS) -o $@ $+ $(LDFLAGS) + +%.o: %.c parse.h + $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $< + +%.c: %.l parse.h + $(LEX) -o $@ $< + +%.c %.h: %.y + $(YACC) -d -o $*.c $*.y + +.SECONDARY: diff --git a/mkcommon b/mkcommon deleted file mode 100644 index 7ef68be..0000000 --- a/mkcommon +++ /dev/null @@ -1,6 +0,0 @@ -%.c: %.ct - (cd .. && mk) - ../ct <$prereq >$target - ex +'norm gg=G' +'wq' $target - -<$HOME/lib/mkcommon diff --git a/mkfile b/mkfile deleted file mode 100644 index ab46194..0000000 --- a/mkfile +++ /dev/null @@ -1,15 +0,0 @@ -PROGS=ct lib -PKGS=glib-2.0 -default:V: all -lib-run:V: lib - ./lib -ct-run:V: ct - ./ct < example/html.ct -ct: ct.o parse.o scan.o -ct.o: parse.h -parse.h parse.c: parse.y - bison -d -o parse.c parse.y -scan.c: scan.l parse.h - flex -o scan.c scan.l -CLEAN=parse.h parse.c scan.c -<$HOME/lib/mkcommon diff --git a/parse.y b/parse.y index f4ce105..530215c 100644 --- a/parse.y +++ b/parse.y @@ -3,53 +3,52 @@ #include #include extern FILE *yyin; +extern int yylineno; int yylex(void); void yyerror(gpointer node, char const *s); -extern int yylineno; -static const char *name; -static GList *code; -static GList *data; +static const char *name = NULL; +static GList *code = NULL; +static GList *data = NULL; %} %error-verbose %parse-param {gpointer root}; -%token START END DATA FMT OUT +%token START END DATA OUT FMT %% input : all | all input ; -all : data | code | print ; +all : data | code | out | fmt ; data : DATA { static int i = 0; data = g_list_prepend(data, g_strdup_printf( - "#line %d \"%s\"\n" "static char data%d[] = \"%s\";\n", - yylineno, name, i, g_strescape($1, ""))); + i, g_strescape($1, ""))); code = g_list_prepend(code, g_strdup_printf( - "#line %d \"%s\"\n" "fwrite(data%d, sizeof(data%d)-1, 1, stdout);\n", - yylineno, name, i, i)); + i, i)); i++; }; code : START DATA END { + code = g_list_prepend(code, g_strdup_printf("#line %d \"%s\"\n", yylineno, name)); code = g_list_prepend(code, g_strdup_printf("%s\n", $2)); }; -print : START FMT DATA END { - code = g_list_prepend(code, g_strdup_printf("printf(%s);\n", $3)); +out : START OUT DATA END { + code = g_list_prepend(code, g_strdup_printf("printf(\"%%s\", %s);\n", $3)); }; -print : START OUT DATA END { - code = g_list_prepend(code, g_strdup_printf("printf(\"%%s\", %s);\n", $3)); +fmt : START FMT DATA END { + code = g_list_prepend(code, g_strdup_printf("printf(%s);\n", $3)); }; %% -gpointer parse(FILE *input, const char *_name, +gpointer parse(const char *_name, FILE *_input, GList **_data, GList **_code) { - yyin = input; name = _name; + yyin = _input; yyparse(NULL); *_data = data; *_code = code; diff --git a/scan.l b/scan.l index 44e7af6..b080e5a 100644 --- a/scan.l +++ b/scan.l @@ -8,6 +8,7 @@ %option nounput %option noinput %option yylineno +%option never-interactive /* %option nodebug */ START [ \t]*<% END [ \t]*%> -- 2.43.2