changeset 24:692da6202633

index stub + sorted dir for comments, category names, archive entries
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Thu, 05 Feb 2009 15:59:55 -0500
parents f0dbfa85ce14
children 9be67550f0bf
files Makefile dir.c dir.h html.c index.c post.c sar.c sar.h
diffstat 8 files changed, 199 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Wed Feb 04 16:29:43 2009 -0500
+++ b/Makefile	Thu Feb 05 15:59:55 2009 -0500
@@ -1,12 +1,15 @@
 CC=gcc
 CFLAGS=-Wall -g -O2 -std=c99 -D_POSIX_C_SOURCE=199309 -lrt
 
-FILES=sar.c post.c xattr.c html.c
+FILES=sar.c post.c xattr.c html.c dir.c
 
-all: story
+all: story index
 
 clean:
-	rm -f story
+	rm -f story index
+
+index: index.c $(FILES)
+	$(CC) $(CFLAGS) -o $@ index.c $(FILES)
 
 story: story.c $(FILES)
 	$(CC) $(CFLAGS) -o $@ story.c $(FILES)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dir.c	Thu Feb 05 15:59:55 2009 -0500
@@ -0,0 +1,67 @@
+#define _XOPEN_SOURCE 500
+#include <stdlib.h>
+#include <dirent.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#include "dir.h"
+#include "post.h"
+
+#define LIST_BLOCK_SIZE		128
+
+static int cmp_asc(const void *a, const void *b)
+{
+	char *as = *(char**)a, *bs = *(char**)b;
+
+	return strcmp(as, bs);
+}
+
+static int cmp_desc(const void *a, const void *b)
+{
+	char *as = *(char**)a, *bs = *(char**)b;
+
+	return -strcmp(as, bs);
+}
+
+int sorted_readdir_loop(DIR *dir, struct post *post,
+			void(*f)(struct post*, char*, void*), void *data,
+			int updown)
+{
+	struct dirent *de;
+	char **list = NULL;
+	int size = 0;
+	int count = 0;
+	int i;
+
+	while((de = readdir(dir))) {
+		if (!strcmp(de->d_name, ".") ||
+		    !strcmp(de->d_name, ".."))
+			continue;
+
+		if (!list || count == size) {
+			size += LIST_BLOCK_SIZE;
+			list = realloc(list, sizeof(char*)*size);
+			if (!list) {
+				printf("%s: couldn't realloc\n", __func__);
+				return ENOMEM;
+			}
+		}
+
+		list[count] = strdup(de->d_name);
+		count++;
+	}
+
+	if (updown == SORT_ASC)
+		qsort(list, count, sizeof(char*), cmp_asc);
+	else
+		qsort(list, count, sizeof(char*), cmp_desc);
+
+	for(i=0; i<count; i++) {
+		f(post, list[i], data);
+		free(list[i]);
+	}
+
+	return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dir.h	Thu Feb 05 15:59:55 2009 -0500
@@ -0,0 +1,13 @@
+#ifndef __DIR_H
+#define __DIR_H
+
+#include "post.h"
+
+#define SORT_ASC	0
+#define SORT_DESC	1
+
+extern int sorted_readdir_loop(DIR *dir, struct post *post,
+			       void(*f)(struct post*, char*, void*),
+			       void *data, int updown);
+
+#endif
--- a/html.c	Wed Feb 04 16:29:43 2009 -0500
+++ b/html.c	Thu Feb 05 15:59:55 2009 -0500
@@ -9,6 +9,7 @@
 
 #include "sar.h"
 #include "html.h"
+#include "dir.h"
 
 /************************************************************************/
 /*                                POST                                  */
@@ -62,11 +63,11 @@
 
 void html_story(struct post *post)
 {
-	cat(post, NULL, "templates/story-top.html", repltab_html);
+	cat(post, NULL, "templates/story-top.html", repltab_story_html);
 
 	__invoke_for_each_post_cat(post, __story_cat_item);
 
-	cat(post, NULL, "templates/story-middle.html", repltab_html);
+	cat(post, NULL, "templates/story-middle.html", repltab_story_html);
 
 	cat_post(post);
 
@@ -87,68 +88,76 @@
 
 void html_comments(struct post *post)
 {
-	cat(post, NULL, "templates/story-comment-head.html", repltab_html);
+	cat(post, NULL, "templates/story-comment-head.html", repltab_story_html);
 
 	invoke_for_each_comment(post, __html_comment);
 
-	cat(post, NULL, "templates/story-comment-tail.html", repltab_html);
+	cat(post, NULL, "templates/story-comment-tail.html", repltab_story_html);
 }
 
 /************************************************************************/
 /*                                 SIDEBAR                              */
 /************************************************************************/
-static void __invoke_for_each_cat(struct post *post, char *prefix, void(*f)(struct post*, char*))
+static void __invoke_for_each_cat(struct post *post, char *prefix,
+				  void(*f)(struct post*, char*));
+
+static void __each_cat_helper(struct post *post, char *name, void *data)
 {
-	struct stat statbuf;
+	char *prefix = ((char**)data)[0];
+	void(*f)(struct post*, char*) = ((void**)data)[1];
+
 	char path[FILENAME_MAX];
-	struct dirent *de;
+	struct stat statbuf;
+	int ret;
+
+	snprintf(path, FILENAME_MAX, "data/by-category/%s/%s", prefix, name);
+
+	ret = lstat(path, &statbuf);
+	if (ret == -1) {
+		fprintf(post->out, "stat failed\n");
+		return;
+	}
+
+	if (!S_ISDIR(statbuf.st_mode))
+		return;
+
+	f(post, path+2+17);
+	__invoke_for_each_cat(post, path+17, f);
+}
+
+static void __invoke_for_each_cat(struct post *post, char *prefix,
+				  void(*f)(struct post*, char*))
+{
+	char path[FILENAME_MAX];
 	DIR *dir;
-	int ret;
+	void *plist[2] = {prefix, f};
 
 	snprintf(path, FILENAME_MAX, "data/by-category/%s", prefix);
 	dir = opendir(path);
 	if (!dir)
 		return;
 
-	while((de = readdir(dir))) {
-		if (!strcmp(de->d_name, ".") ||
-		    !strcmp(de->d_name, ".."))
-			continue;
-
-		snprintf(path, FILENAME_MAX, "data/by-category/%s/%s", prefix, de->d_name);
-
-		ret = lstat(path, &statbuf);
-		if (ret == -1) {
-			fprintf(post->out, "stat failed\n");
-			break;
-		}
-
-		if (!S_ISDIR(statbuf.st_mode))
-			continue;
-
-		f(post, path+2+17);
-		__invoke_for_each_cat(post, path+17, f);
-	}
+	sorted_readdir_loop(dir, post, __each_cat_helper, plist, SORT_ASC);
 
 	closedir(dir);
 }
 
+static void __cb_wrap(struct post *post, char *name, void *data)
+{
+	void(*f)(struct post*, char*) = data;
+
+	f(post, name);
+}
+
 static void __invoke_for_each_archive(struct post *post, void(*f)(struct post*, char*))
 {
-	struct dirent *de;
 	DIR *dir;
 
 	dir = opendir("data/by-month");
 	if (!dir)
 		return;
 
-	while((de = readdir(dir))) {
-		if (!strcmp(de->d_name, ".") ||
-		    !strcmp(de->d_name, ".."))
-			continue;
-
-		f(post, de->d_name);
-	}
+	sorted_readdir_loop(dir, post, __cb_wrap, f, SORT_DESC);
 
 	closedir(dir);
 }
@@ -165,15 +174,15 @@
 
 void html_sidebar(struct post *post)
 {
-	cat(post, NULL, "templates/sidebar-top.html", repltab_html);
+	cat(post, NULL, "templates/sidebar-top.html", repltab_story_html);
 
 	__invoke_for_each_cat(post, ".", __sidebar_cat_item);
 
-	cat(post, NULL, "templates/sidebar-middle.html", repltab_html);
+	cat(post, NULL, "templates/sidebar-middle.html", repltab_story_html);
 
 	__invoke_for_each_archive(post, __sidebar_arch_item);
 
-	cat(post, NULL, "templates/sidebar-bottom.html", repltab_html);
+	cat(post, NULL, "templates/sidebar-bottom.html", repltab_story_html);
 }
 
 /************************************************************************/
@@ -181,7 +190,7 @@
 /************************************************************************/
 void html_header(struct post *post)
 {
-	cat(post, NULL, "templates/header.html", repltab_html);
+	cat(post, NULL, "templates/header.html", repltab_story_html);
 }
 
 /************************************************************************/
@@ -189,5 +198,5 @@
 /************************************************************************/
 void html_footer(struct post *post)
 {
-	cat(post, NULL, "templates/footer.html", repltab_html);
+	cat(post, NULL, "templates/footer.html", repltab_story_html);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/index.c	Thu Feb 05 15:59:55 2009 -0500
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "post.h"
+#include "sar.h"
+#include "html.h"
+
+int main(int argc, char **argv)
+{
+	struct timespec s,e;
+	struct post post;
+
+	clock_gettime(CLOCK_REALTIME, &s);
+
+	memset(&post, 0, sizeof(struct post));
+	post.out = stdout;
+	post.title = "Blahg";
+
+	fprintf(post.out, "Content-Type: text/html\n\n");
+
+	html_header(&post);
+	html_sidebar(&post);
+	html_footer(&post);
+
+	post.title = NULL;
+	destroy_post(&post);
+
+	clock_gettime(CLOCK_REALTIME, &e);
+
+	fprintf(post.out, "<!-- time to render: %ld.%09ld seconds -->\n", (int)e.tv_sec-s.tv_sec,
+		e.tv_nsec-s.tv_nsec+((e.tv_sec-s.tv_sec) ? 1000000000 : 0));
+
+	return 0;
+}
--- a/post.c	Wed Feb 04 16:29:43 2009 -0500
+++ b/post.c	Thu Feb 05 15:59:55 2009 -0500
@@ -15,6 +15,7 @@
 #include "post.h"
 #include "xattr.h"
 #include "sar.h"
+#include "dir.h"
 
 void cat(struct post *post, void *data, char *tmpl,
 	 struct repltab_entry *repltab)
@@ -199,14 +200,27 @@
 	free(comm->author);
 }
 
+static void __each_comment_helper(struct post *post, char *name, void *data)
+{
+	void(*f)(struct post*, struct comment*) = data;
+	struct comment comm;
+	int commid;
+
+	commid = atoi(name);
+
+	if (load_comment(post, commid, &comm))
+		return;
+
+	f(post, &comm);
+
+	destroy_comment(&comm);
+}
+
 void invoke_for_each_comment(struct post *post, void(*f)(struct post*,
 							 struct comment*))
 {
 	char path[FILENAME_MAX];
-	struct dirent *de;
 	DIR *dir;
-	struct comment comm;
-	int commid;
 
 	snprintf(path, FILENAME_MAX, "data/posts/%d/comments", post->id);
 
@@ -214,20 +228,7 @@
 	if (!dir)
 		return;
 
-	while((de = readdir(dir))) {
-		if (!strcmp(de->d_name, ".") ||
-		    !strcmp(de->d_name, ".."))
-			continue;
-
-		commid = atoi(de->d_name);
-
-		if (load_comment(post, commid, &comm))
-			break;
-
-		f(post, &comm);
-
-		destroy_comment(&comm);
-	}
+	sorted_readdir_loop(dir, post, __each_comment_helper, f, SORT_ASC);
 
 	closedir(dir);
 }
--- a/sar.c	Wed Feb 04 16:29:43 2009 -0500
+++ b/sar.c	Thu Feb 05 15:59:55 2009 -0500
@@ -17,7 +17,7 @@
 	"July", "August", "September", "October", "November", "December",
 };
 
-static void echo_title(struct post *post, void *data)
+static void echo_story_title(struct post *post, void *data)
 {
 	fprintf(post->out, "%s", post->title);
 }
@@ -40,15 +40,16 @@
 	char path[FILENAME_MAX];
 	struct dirent *de;
 	DIR *dir;
-	int count;
+	int count = 0;
 
 	snprintf(path, FILENAME_MAX, "data/posts/%d/comments", post->id);
 
 	dir = opendir(path);
-	if (!dir)
+	if (!dir) {
+		fprintf(post->out, "No");
 		return;
+	}
 
-	count = 0;
 	while((de = readdir(dir))) {
 		if (!strcmp(de->d_name, ".") ||
 		    !strcmp(de->d_name, ".."))
@@ -62,11 +63,11 @@
 	fprintf(post->out, "%d", count);
 }
 
-static struct repltab_entry __repltab_html[] = {
+static struct repltab_entry __repltab_story_html[] = {
 	{"POSTID",	echo_postid},
 	{"POSTDATE",	echo_postdate},
 	{"POSTTIME",	echo_posttime},
-	{"TITLE",	echo_title},
+	{"TITLE",	echo_story_title},
 	{"COMCOUNT",	echo_comment_count},
 	{"",		NULL},
 };
@@ -106,7 +107,7 @@
 	{"POSTID",	echo_postid},
 	{"POSTDATE",	echo_postdate},
 	{"POSTTIME",	echo_posttime},
-	{"TITLE",	echo_title},
+	{"TITLE",	echo_story_title},
 	{"COMCOUNT",	echo_comment_count},
 	{"COMID",	echo_comment_id},
 	{"COMAUTHOR",	echo_comment_author},
@@ -148,7 +149,7 @@
 	{"",		NULL},
 };
 
-struct repltab_entry *repltab_html = __repltab_html;
+struct repltab_entry *repltab_story_html = __repltab_story_html;
 struct repltab_entry *repltab_comm_html = __repltab_comm_html;
 struct repltab_entry *repltab_cat_html = __repltab_cat_html;
 struct repltab_entry *repltab_arch_html = __repltab_arch_html;
--- a/sar.h	Wed Feb 04 16:29:43 2009 -0500
+++ b/sar.h	Thu Feb 05 15:59:55 2009 -0500
@@ -11,7 +11,7 @@
 extern void sar(struct post *post, void *data, char *ibuf,
 		int size, struct repltab_entry *repltab);
 
-extern struct repltab_entry *repltab_html;
+extern struct repltab_entry *repltab_story_html;
 extern struct repltab_entry *repltab_comm_html;
 extern struct repltab_entry *repltab_cat_html;
 extern struct repltab_entry *repltab_arch_html;