sfeed_opml_import.c (2200B)
1 #include <stdio.h> 2 #include <strings.h> 3 4 #include "util.h" 5 #include "xml.h" 6 7 static XMLParser parser; /* XML parser state */ 8 static char text[256], title[256], xmlurl[2048]; 9 10 static void 11 printsafe(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 25 static void 26 xmltagstart(XMLParser *p, const char *t, size_t tl) 27 { 28 text[0] = title[0] = xmlurl[0] = '\0'; 29 } 30 31 static void 32 xmltagend(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 54 static void 55 xmlattr(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 69 static void 70 xmlattrentity(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[16]; 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 82 int 83 main(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 }