sfeed

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

sfeed_opml_import.c (2199B)


      1#include <stdio.h>
      2#include <strings.h>
      3
      4#include "util.h"
      5#include "xml.h"
      6
      7static XMLParser parser; /* XML parser state */
      8static char text[256], title[256], xmlurl[2048];
      9
     10static void
     11printsafe(const char *s)
     12{
     13	for (; *s; s++) {
     14		if (ISCNTRL((unsigned char)*s))
     15			continue;
     16		else if (*s == '\\')
     17			fputs("\\\\", stdout);
     18		else if (*s == '\'')
     19			fputs("'\\''", stdout);
     20		else
     21			putchar(*s);
     22	}
     23}
     24
     25static void
     26xmltagstart(XMLParser *p, const char *t, size_t tl)
     27{
     28	text[0] = title[0] = xmlurl[0] = '\0';
     29}
     30
     31static void
     32xmltagend(XMLParser *p, const char *t, size_t tl, int isshort)
     33{
     34	if (strcasecmp(t, "outline"))
     35		return;
     36
     37	if (xmlurl[0]) {
     38		fputs("\tfeed '", stdout);
     39		/* prefer title over text attribute */
     40		if (title[0])
     41			printsafe(title);
     42		else if (text[0])
     43			printsafe(text);
     44		else
     45			fputs("unnamed", stdout);
     46		fputs("' '", stdout);
     47		printsafe(xmlurl);
     48		fputs("'\n", stdout);
     49	}
     50
     51	text[0] = title[0] = xmlurl[0] = '\0';
     52}
     53
     54static void
     55xmlattr(XMLParser *p, const char *t, size_t tl, const char *n, size_t nl,
     56	const char *v, size_t vl)
     57{
     58	if (strcasecmp(t, "outline"))
     59		return;
     60
     61	if (!strcasecmp(n, "text"))
     62		strlcat(text, v, sizeof(text));
     63	else if (!strcasecmp(n, "title"))
     64		strlcat(title, v, sizeof(title));
     65	else if (!strcasecmp(n, "xmlurl"))
     66		strlcat(xmlurl, v, sizeof(xmlurl));
     67}
     68
     69static void
     70xmlattrentity(XMLParser *p, const char *t, size_t tl, const char *n, size_t nl,
     71	const char *v, size_t vl)
     72{
     73	char buf[8];
     74	int len;
     75
     76	if ((len = xml_entitytostr(v, buf, sizeof(buf))) > 0)
     77		xmlattr(p, t, tl, n, nl, buf, len);
     78	else
     79		xmlattr(p, t, tl, n, nl, v, vl);
     80}
     81
     82int
     83main(void)
     84{
     85	if (pledge("stdio", NULL) == -1)
     86		err(1, "pledge");
     87
     88	parser.xmlattr = xmlattr;
     89	parser.xmlattrentity = xmlattrentity;
     90	parser.xmltagstart = xmltagstart;
     91	parser.xmltagend = xmltagend;
     92
     93	fputs(
     94	    "#sfeedpath=\"$HOME/.sfeed/feeds\"\n"
     95	    "\n"
     96	    "# list of feeds to fetch:\n"
     97	    "feeds() {\n"
     98	    "	# feed <name> <feedurl> [basesiteurl] [encoding]\n", stdout);
     99	/* NOTE: GETNEXT is defined in xml.h for inline optimization */
    100	xml_parse(&parser);
    101	fputs("}\n", stdout);
    102
    103	checkfileerror(stdin, "<stdin>", 'r');
    104	checkfileerror(stdout, "<stdout>", 'w');
    105
    106	return 0;
    107}