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 }