1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "yxmllib.h"
#define BUFSIZE 8096
typedef struct buffer {
int len;
char *buffer;
} buffer;
buffer *buffer_new() {
buffer *buf = malloc(sizeof(buffer));
buf->buffer = malloc(BUFSIZE);
if (!buf || !buf->buffer) {
fprintf(stderr, "Could not allocate memory for buffer struct.\n");
exit(1);
}
buf->len = 0;
return buf;
}
buffer *buffer_reset(buffer *buf) {
buf->buffer = memset(buf->buffer, 0, BUFSIZE);
buf->len = 0;
return buf;
}
buffer *buffer_append(buffer *buf, char *data) {
for (int i = 0; data[i]; i++) {
buf->buffer[buf->len] = data[i];
buf->len++;
}
return buf;
}
int process(char *fn, yxml_t *state) {
size_t filelen;
char *parsebuffer;
int inelement;
buffer *contentbuf;
FILE* f = fopen(fn, "rb");
if (!f) {
fprintf(stderr, "Could not open %s.", fn);
perror("Error:");
return 1;
}
// get file size
fseek(f, 0L, SEEK_END);
filelen = ftell(f);
rewind(f);
parsebuffer = calloc(1, filelen+1);
if (!parsebuffer) {
fprintf(stderr, "Could not allocate memory for file %s.\n", fn);
fclose(f);
return 1;
}
if (fread(parsebuffer, filelen, 1 , f) != 1) {
fprintf(stderr, "Could not read file into memory for file %s.\n", fn);
free(parsebuffer);
fclose(f);
return 1;
}
fclose(f);
inelement = 0;
contentbuf = buffer_new();
yxml_init(state, state+1, BUFSIZE);
for (; *parsebuffer; parsebuffer++) {
yxml_ret_t r = yxml_parse(state, *parsebuffer);
//fprintf(stderr, "parse_state: %d\n", r);
if(r < 0) {
printf("Parsing error at %s: line %u, byte %lu, offset %lu\n",
fn, state->line, state->byte, state->total);
return 1;
}
switch(r) {
case YXML_ELEMSTART:
if (!strcmp(state->elem, "article-title")) {
inelement = 1;
}
break;
case YXML_CONTENT:
if (inelement) {
buffer_append(contentbuf, state->data);
}
break;
case YXML_ELEMEND:
if (strcmp(state->elem, "article-title")) {
break;
}
inelement = 0;
printf("%s\n", contentbuf->buffer);
buffer_reset(contentbuf);
break;
}
}
return 0;
}
int main(int argc, char *argv[]) {
yxml_t *state = malloc(sizeof(yxml_t) + BUFSIZE);
for (int i = 1; i < argc; i++) {
process(argv[i], state);
}
return 0;
}
|