main.c - randomcrap - random crap programs of varying quality
 (HTM) git clone git://git.codemadness.org/randomcrap
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       main.c (3222B)
       ---
            1 #include <err.h>
            2 #include <stdio.h>
            3 #include <string.h>
            4 #include <strings.h>
            5 
            6 #include "xml.h"
            7 
            8 #ifdef __OpenBSD__
            9 #include <unistd.h>
           10 #else
           11 #define pledge(p1,p2) 0
           12 #endif
           13 
           14 /* ctype-like macros, but always compatible with ASCII / UTF-8 */
           15 #define ISCNTRL(c) ((c) < ' ' || (c) == 0x7f)
           16 
           17 #define ATTRCMP strcasecmp
           18 #define TAGCMP strcasecmp
           19 
           20 enum ContentType { TypeNone, TypeTitle, TypeDescription, TypeUrl, TypeImage, TypeVideo };
           21 static enum ContentType currenttype;
           22 
           23 static char title[4096];
           24 static char description[4096];
           25 static char image[4096];
           26 static char url[4096];
           27 static char video[4096];
           28 
           29 static char data[4096]; /* temporary buffer */
           30 
           31 static void
           32 printfield(const char *s)
           33 {
           34         for (; *s; s++) {
           35                 if (*s == '\n')
           36                         putchar(' '); /* newline to space */
           37                 else if (ISCNTRL((unsigned char)*s))
           38                         continue; /* ignore control characters */
           39                 putchar(*s);
           40         }
           41 }
           42 
           43 void
           44 xmlattr(XMLParser *x, const char *t, size_t tl, const char *a, size_t al,
           45         const char *v, size_t vl)
           46 {
           47         if (TAGCMP(t, "meta"))
           48                 return;
           49 
           50         if (!ATTRCMP(a, "content")) {
           51                 strlcat(data, v, sizeof(data));
           52         } else if (!ATTRCMP(a, "property")) {
           53                 if (!ATTRCMP(v, "og:title"))
           54                         currenttype = TypeTitle;
           55                 else if (!ATTRCMP(v, "og:description"))
           56                         currenttype = TypeDescription;
           57                 else if (!ATTRCMP(v, "og:url"))
           58                         currenttype = TypeUrl;
           59                 else if (!ATTRCMP(v, "og:image"))
           60                         currenttype = TypeImage;
           61                 else if (!ATTRCMP(v, "og:video"))
           62                         currenttype = TypeVideo;
           63                 else
           64                         currenttype = TypeNone;
           65         }
           66 }
           67 
           68 void
           69 xmlattrentity(XMLParser *x, const char *t, size_t tl, const char *a, size_t al,
           70               const char *v, size_t vl)
           71 {
           72         char buf[8];
           73         int len;
           74 
           75         if (TAGCMP(t, "meta"))
           76                 return;
           77 
           78         /* try to translate entity, else just pass as data to
           79          * xmlattr handler. */
           80         if ((len = xml_entitytostr(v, buf, sizeof(buf))) > 0)
           81                 xmlattr(x, t, tl, a, al, buf, (size_t)len);
           82         else
           83                 xmlattr(x, t, tl, a, al, v, vl);
           84 }
           85 
           86 void
           87 xmltagstartparsed(XMLParser *x, const char *t, size_t tl, int isshort)
           88 {
           89         if (strcmp(t, "meta"))
           90                 return;
           91 
           92         switch (currenttype) {
           93         case TypeTitle:
           94                 strlcpy(title, data, sizeof(title));
           95                 break;
           96         case TypeDescription:
           97                 strlcpy(description, data, sizeof(description));
           98                 break;
           99         case TypeUrl:
          100                 strlcpy(url, data, sizeof(url));
          101                 break;
          102         case TypeImage:
          103                 strlcpy(image, data, sizeof(image));
          104                 break;
          105         case TypeVideo:
          106                 strlcpy(video, data, sizeof(video));
          107                 break;
          108         default:
          109                 break;
          110         }
          111 }
          112 
          113 void
          114 xmltagstart(XMLParser *x, const char *t, size_t tl)
          115 {
          116         if (strcmp(t, "meta"))
          117                 return;
          118 
          119         data[0] = '\0';
          120         currenttype = TypeNone;
          121 }
          122 
          123 int
          124 main(void)
          125 {
          126         XMLParser x = { 0 };
          127 
          128         if (pledge("stdio", NULL) == -1)
          129                 err(1, "pledge");
          130 
          131         x.xmlattr = xmlattr;
          132         x.xmlattrentity = xmlattrentity;
          133         x.xmltagstartparsed = xmltagstartparsed;
          134         x.xmltagstart = xmltagstart;
          135 
          136         xml_parse(&x);
          137 
          138         if (title[0]) {
          139                 printf("Title:       ");
          140                 printfield(title);
          141                 putchar('\n');
          142         }
          143         if (description[0]) {
          144                 printf("Description: ");
          145                 printfield(description);
          146                 putchar('\n');
          147         }
          148         if (url[0]) {
          149                 printf("URL:         ");
          150                 printfield(url);
          151                 putchar('\n');
          152         }
          153         if (image[0]) {
          154                 printf("Image:       ");
          155                 printfield(image);
          156                 putchar('\n');
          157         }
          158         if (video[0]) {
          159                 printf("Video:       ");
          160                 printfield(video);
          161                 putchar('\n');
          162         }
          163 
          164         return 0;
          165 }