sfeed

Simple RSS and Atom feed parser
git clone https://git.sinitax.com/codemadness/sfeed
Log | Files | Refs | README | LICENSE | Upstream | sfeed.txt

commit 3d972927d748267b0e999ef85bc56bab9e771b5d
parent 51480739874ea7070d37a7a09b0df09efedbae83
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Sun,  2 Aug 2015 13:08:12 +0200

refactor print, decodefield into xmlencode

... put specific formatting-logic per program (printcontent()).

Diffstat:
Msfeed_frames.c | 38+++++++++++++++++++++++++++++---------
Msfeed_html.c | 14+++++++-------
Mutil.c | 43+++++++++----------------------------------
Mutil.h | 4+---
4 files changed, 46 insertions(+), 53 deletions(-)

diff --git a/sfeed_frames.c b/sfeed_frames.c @@ -24,6 +24,26 @@ static unsigned long totalnew = 0; static struct feed **feeds = NULL; +/* Unescape / decode fields printed by string_print_encoded() + * "\\" to "\", "\t", to TAB, "\n" to newline. Unrecognised escape sequences + * are ignored: "\z" etc. Call `fn` on each escaped character. */ +void +printcontent(const char *s, FILE *fp) +{ + for (; *s; s++) { + if (*s == '\\') { + switch (*(++s)) { + case '\0': return; /* ignore */ + case '\\': fputc('\\', fp); break; + case 't': fputc('\t', fp); break; + case 'n': fputc('\n', fp); break; + } + } else { + fputc((int)*s, fp); + } + } +} + /* normalize path names, transform to lower-case and replace non-alpha and * non-digit with '-' */ static size_t @@ -83,11 +103,11 @@ printfeed(FILE *fpitems, FILE *fpin, struct feed *f) /* menu if not unnamed */ if (f->name[0]) { fputs("<h2 id=\"", fpitems); - print(f->name, fpitems, xmlencode); + xmlencode(f->name, fpitems); fputs("\"><a href=\"#", fpitems); - print(f->name, fpitems, xmlencode); + xmlencode(f->name, fpitems); fputs("\">", fpitems); - print(f->name, fpitems, xmlencode); + xmlencode(f->name, fpitems); fputs("</a></h2>\n", fpitems); } @@ -108,14 +128,14 @@ printfeed(FILE *fpitems, FILE *fpin, struct feed *f) "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /></head>\n" "<body class=\"frame\"><div class=\"content\">" "<h2><a href=\"", fpcontent); - print(fields[FieldLink], fpcontent, xmlencode); + xmlencode(fields[FieldLink], fpcontent); fputs("\">", fpcontent); - print(fields[FieldTitle], fpcontent, xmlencode); + xmlencode(fields[FieldTitle], fpcontent); fputs("</a></h2>", fpcontent); /* NOTE: this prints the raw HTML of the feed, this is * potentially dangerous, it is up to the user / browser * to trust a feed it's HTML content. */ - decodefield(fields[FieldContent], fpcontent, fputc); + printcontent(fields[FieldContent], fpcontent); fputs("</div></body></html>", fpcontent); fclose(fpcontent); } @@ -144,7 +164,7 @@ printfeed(FILE *fpitems, FILE *fpin, struct feed *f) fputs("<a href=\"", fpitems); fputs(filepath, fpitems); fputs("\" target=\"content\">", fpitems); - print(fields[FieldTitle], fpitems, xmlencode); + xmlencode(fields[FieldTitle], fpitems); fputs("</a>", fpitems); if (isnew) fputs("</u></b>", fpitems); @@ -213,11 +233,11 @@ main(int argc, char *argv[]) fputs("<a class=\"n\" href=\"items.html#", fpmenu); else fputs("<a href=\"items.html#", fpmenu); - print(f->name, fpmenu, xmlencode); + xmlencode(f->name, fpmenu); fputs("\" target=\"items\">", fpmenu); if (f->totalnew > 0) fputs("<b><u>", fpmenu); - print(f->name, fpmenu, xmlencode); + xmlencode(f->name, fpmenu); fprintf(fpmenu, " (%lu)", f->totalnew); if (f->totalnew > 0) fputs("</u></b>", fpmenu); diff --git a/sfeed_html.c b/sfeed_html.c @@ -24,11 +24,11 @@ printfeed(FILE *fp, struct feed *f) if (f->name[0] != '\0') { fputs("<h2 id=\"", stdout); - print(f->name, stdout, xmlencode); + xmlencode(f->name, stdout); fputs("\"><a href=\"#", stdout); - print(f->name, stdout, xmlencode); + xmlencode(f->name, stdout); fputs("\">", stdout); - print(f->name, stdout, xmlencode); + xmlencode(f->name, stdout); fputs("</a></h2>\n", stdout); } fputs("<table cellpadding=\"0\" cellspacing=\"0\">\n", stdout); @@ -53,10 +53,10 @@ printfeed(FILE *fp, struct feed *f) fputs("<b><u>", stdout); if (islink) { fputs("<a href=\"", stdout); - print(fields[FieldLink], stdout, xmlencode); + xmlencode(fields[FieldLink], stdout); fputs("\">", stdout); } - print(fields[FieldTitle], stdout, xmlencode); + xmlencode(fields[FieldTitle], stdout); if (islink) fputs("</a>", stdout); if (isnew) @@ -126,11 +126,11 @@ main(int argc, char *argv[]) fputs("<li class=\"n\"><a href=\"#", stdout); else fputs("<li><a href=\"#", stdout); - print(f->name, stdout, xmlencode); + xmlencode(f->name, stdout); fputs("\">", stdout); if (f->totalnew > 0) fputs("<b><u>", stdout); - print(f->name, stdout, xmlencode); + xmlencode(f->name, stdout); fprintf(stdout, " (%lu)", f->totalnew); if (f->totalnew > 0) fputs("</u></b>", stdout); diff --git a/util.c b/util.c @@ -200,47 +200,22 @@ strtotime(const char *s, time_t *t) return 0; } +/* Escape characters below as HTML 2.0 / XML 1.0. */ void -print(const char *s, FILE *fp, int (*fn)(int, FILE *)) -{ - for (; *s; s++) - fn((int)*s, fp); -} - -/* Unescape / decode fields printed by string_print_encoded() - * "\\" to "\", "\t", to TAB, "\n" to newline. Unrecognised escape sequences - * are ignored: "\z" etc. Call `fn` on each escaped character. */ -void -decodefield(const char *s, FILE *fp, int (*fn)(int, FILE *)) +xmlencode(const char *s, FILE *fp) { for (; *s; s++) { - if (*s == '\\') { - switch (*(++s)) { - case '\\': fn('\\', fp); break; - case 't': fn('\t', fp); break; - case 'n': fn('\n', fp); break; - case '\0': return; - } - } else { - fn((int)*s, fp); + switch(*s) { + case '<': fputs("&lt;", fp); break; + case '>': fputs("&gt;", fp); break; + case '\'': fputs("&apos;", fp); break; + case '&': fputs("&amp;", fp); break; + case '"': fputs("&quot;", fp); break; + default: fputc(*s, fp); } } } -/* Escape characters below as HTML 2.0 / XML 1.0. */ -int -xmlencode(int c, FILE *fp) -{ - switch(c) { - case '<': return fputs("&lt;", fp); - case '>': return fputs("&gt;", fp); - case '\'': return fputs("&apos;", fp); - case '&': return fputs("&amp;", fp); - case '"': return fputs("&quot;", fp); - } - return fputc(c, fp); -} - /* Some implementations of basename(3) return a pointer to a static * internal buffer (OpenBSD). Others modify the contents of `path` (POSIX). * This is a wrapper function that is compatible with both versions. diff --git a/util.h b/util.h @@ -26,13 +26,11 @@ enum { FieldUnixTimestamp = 0, FieldTimeFormatted, FieldTitle, FieldLink, FieldLast }; int absuri(const char *, const char *, char *, size_t); -void decodefield(const char *, FILE *, int (*)(int, FILE *)); int encodeuri(const char *, char *, size_t); int parseline(char **, size_t *, char **, unsigned int, int, FILE *); int parseuri(const char *, struct uri *, int); -void print(const char *, FILE *, int (*)(int, FILE *)); int strtotime(const char *, time_t *); char * xbasename(const char *); -int xmlencode(int, FILE *); +void xmlencode(const char *, FILE *);