[ekg2-commit] ekg2: drafts.c (HEAD) jogger.c (HEAD) [peres]

CVS commit cvs w toxygen.net
Nie, 6 Maj 2007, 02:06:48 CEST


Module name:	ekg2
Changes by:	peres	2007-05-06 02:06:46

Modified files:
	drafts.c jogger.c

Log message:
- moving open/close file code into function,
- adding some syntax checking in /prepare.
TODO:
- value-checking,
- iconvize keys&values,
- some function for retrieving path incl. homedir.

Index: drafts.c
===================================================================
RCS file: /home/cvs/ekg2/plugins/jogger/drafts.c,v
diff -d -u -r1.1 -r1.2
--- drafts.c	5 May 2007 22:11:46 -0000	1.1
+++ drafts.c	6 May 2007 00:06:45 -0000	1.2
@@ -25,13 +25,164 @@
 
 #include <ekg/commands.h>
 #include <ekg/debug.h>
+#include <ekg/stuff.h>
 #include <ekg/themes.h>
 #include <ekg/windows.h>
 #include <ekg/xmalloc.h>
 
+	/* XXX, iconvize */
+const char *jogger_header_keys[] = {
+	"tytul:",	"temat:",	"subject:",	"tytuł:",		NULL,
+	"kategoria:",	"category:",	"kategorie:",	"categories",		NULL,
+	"tag:",									NULL,
+	"poziom:",	"level:",						NULL,
+	"trackback:",								NULL, /* 5 - XXX check URI? */
+	"tidy",									NULL, /* 6 - XXX jhv, 1st */
+	"komentarze",	"comments:",						NULL, /* 7 - XXX jhv, 1&2 */
+	NULL
+};
+
+const char *jogger_header_values[] = {
+	"off",		"no",		"nie",		"wylacz",	"wyłącz",
+	"on",		"yes",		"tak",		"wlacz",	"włącz",
+	"0",		"1",							NULL,
+
+	"jogger",	"2",							NULL,
+	NULL
+};
+
+/**
+ * jogger_openfile()
+ *
+ * Opens given file and mmaps it.
+ *
+ * @param	fn	- filename to open.
+ * @param	fd	- pointer to store fd.
+ * @param	fs	- pointer to store filesize.
+ *
+ * @return	Pointer to file contents or NULL on failure.
+ *
+ * @sa	jogger_closefile	- close such opened file.
+ */
+static char *jogger_openfile(const char *fn, int *fd, int *fs) {
+	char *out;
+
+	if ((*fd = open(fn, O_RDONLY|O_NONBLOCK)) == -1) { /* we use O_NONBLOCK to get rid of FIFO problems */
+		if (errno == ENXIO)
+			print("jogger_nonfile");
+		else
+			print("jogger_cantopen");
+		return NULL;
+	}
+
+	{
+		struct stat st;
+
+		if ((fstat(*fd, &st) == -1) || !S_ISREG(st.st_mode)) {
+			close(*fd);
+			print("jogger_nonfile");
+			return NULL;
+		}
+		if ((*fs = st.st_size) == 0) {
+			close(*fd);
+			print("jogger_emptyfile");
+			return NULL;
+		}
+	}
+
+	if ((out = mmap(NULL, *fs, PROT_READ, MAP_PRIVATE, *fd, 0)) == MAP_FAILED) {
+		close(*fd);
+		print("jogger_cantread");
+		return NULL;
+	}
+
+	return out;
+}
+
+/**
+ * jogger_closefile()
+ *
+ * Closes file opened by jogger_openfile().
+ *
+ * @param	fd	- returned fd.
+ * @param	data	- returned data.
+ * @param	fs	- returned filesize.
+ *
+ * @sa	jogger_openfile	- open and mmap file.
+ */
+static void jogger_closefile(int fd, char *data, int fs) {
+	munmap(data, fs);
+	close(fd);
+}
+
 COMMAND(jogger_prepare) {
-		/* XXX, check file and contents */
+	int fd, fs;
+	char *entry, *s;
+	int seen = 0;
+
+	if (!(entry = jogger_openfile(params[0], &fd, &fs)))
+		return -1;
+	s = entry;
+
+	s += xstrspn(s, " \n\r");	/* get on to first real char */
+	while (*s == '(') {	/* parse headers */
+		const char *sep		= xstrchr(s, ':');
+		const char *end		= xstrchr(s, ')');
+		const char *next	= xstrchr(s, '\n');
+
+		char tmp[12];		/* longest correct key has 10 chars + '(' + \0 */
+		xstrncpy(tmp, s, 11);
+		tmp[11] = 0;
+		xstrtr(tmp, '\n', 0);
+
+		if (!sep || !end || !next || (sep > end) || (end+1+xstrspn(end+1, " ") != next)) {
+			print("jogger_warning_brokenheader", tmp);
+			if (!next)
+				s = entry+fs;
+		} else if ((*(s+1) == ' ') || (*(sep-1) == ' '))
+			print("jogger_warning_wrongkey_spaces", tmp);
+		else {
+			int i = 0;
+			const char **p = (sep-s < 12 ? jogger_header_keys : NULL);
 
+			for (; *p; i++, p++) { /* awaiting second NULL here */
+				for (; *p; p++) { /* awaiting single NULL here */
+					if (!xstrncasecmp(tmp+1, *p, xstrlen(*p))) {
+						if (seen & (1<<i))
+							print("jogger_warning_duplicated_header", tmp);
+						else
+							seen |= (1<<i);
+						break;
+					}
+				}
+				if (*p)
+					break;
+			}
+
+			if (!p || !*p)
+				print("jogger_warning_wrongkey", tmp);
+		}
+
+		s = next+1;
+	}
+
+	s += xstrspn(s, " \n\r");	/* get on to first real char (again) */
+	if (*s == '(') {
+		char tmp[11];
+		xstrncpy(tmp, s, 10);
+		tmp[10] = 0;
+		xstrtr(tmp, '\n', 0);
+		print("jogger_warning_mislocated_header", tmp);
+	}
+	if (!xstrstr(s, "<EXCERPT>") && (fs - (s-entry) > 4096)) {
+		char tmp[21];
+		xstrncpy(tmp, s+4086, 20);
+		tmp[20] = 0;
+		xstrtr(tmp, '\n', ' '); /* sanitize */
+		print("jogger_warning_noexcerpt", tmp);
+	}
+
+	jogger_closefile(fd, entry, fs);
 	session_set(session, "entry_file", params[0]);
 	printq("jogger_prepared", params[0]);
 	return 0;
@@ -47,35 +198,12 @@
 		return -1;
 	}
 
-	if ((fd = open(fn, O_RDONLY|O_NONBLOCK)) == -1) { /* we use O_NONBLOCK to get rid of FIFO problems */
-		if (errno == ENXIO)
-			printq("jogger_nonfile");
-		else
-			printq("jogger_cantopen");
-		return -1;
-	}
-
-	{
-		struct stat st;
-
-		if ((fstat(fd, &st) == -1) || !S_ISREG(st.st_mode)) {
-			close(fd);
-			printq("jogger_nonfile");
-			return -1;
-		}
-		fs = st.st_size;
-	}
-
-	if ((entry = mmap(NULL, fs, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
-		close(fd);
-		printq("jogger_cantread");
+	if (!(entry = jogger_openfile(fn, &fd, &fs)))
 		return -1;
-	}
 
 	command_exec("jogger:", session, entry, 0);
 
-	munmap(entry, fs);
-	close(fd);
-	session_set(session, "entry_file");	/* XXX: reset always or only if using it? */
+	jogger_closefile(fd, entry, fs);
+	session_set(session, "entry_file", NULL);	/* XXX: reset always or only if using it? */
 	return 0;
 }

Index: jogger.c
===================================================================
RCS file: /home/cvs/ekg2/plugins/jogger/jogger.c,v
diff -d -u -r1.13 -r1.14
--- jogger.c	5 May 2007 22:11:46 -0000	1.13
+++ jogger.c	6 May 2007 00:06:45 -0000	1.14
@@ -226,6 +226,14 @@
 	format_add("jogger_cantopen", _("%! Unable to open entry file!"), 1);
 	format_add("jogger_nonfile", _("%! Given path doesn't appear to be regular file!"), 1);
 	format_add("jogger_cantread", _("%! Unable to read entry file!"), 1);
+	format_add("jogger_emptyfile", _("%! File is empty!"), 1);
+	format_add("jogger_warning", _("%> During QA check of the entry, following warnings have been issued:"), 1);
+	format_add("jogger_warning_brokenheader", _("%> %|* Header with broken syntax found: %c%1%n..."), 1);
+	format_add("jogger_warning_wrongkey", _("%> %|* Header contains unknown/wrong key: %c%1%n..."), 1);
+	format_add("jogger_warning_wrongkey_spaces", _("%> %|* Key in header mustn't be followed or preceeded by spaces: %c%1%n..."), 1);
+	format_add("jogger_warning_duplicated_header", _("%> %|* Duplicated header found: %c%1%n..."), 1);
+	format_add("jogger_warning_mislocated_header", _("%> %|* Mislocated header (?): %c%1%n..."), 1);
+	format_add("jogger_warning_noexcerpt", _("%> %|* Entry text size exceeds 4096 bytes, but no <EXCERPT> tag has been found. It will be probably cut by Jogger near: ...%c%1%n..."), 1);
 #endif
 	return 0;
 }


Więcej informacji o liście dyskusyjnej ekg2-commit