glue.c - bag - Dutch BAG Kadaster Extract parser (subset)
(HTM) git clone git://git.codemadness.org/bag
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
glue.c (2865B)
---
1 #if WIN32
2 #include <io.h> /* for setmode() */
3 #endif
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8
9 #define PUTCHAR putchar
10 #define FPUTS fputs
11
12 #define FieldLast 8
13
14 struct string {
15 char *data;
16 size_t len;
17 size_t cap;
18 };
19
20 static struct string mergedfields[FieldLast];
21 static char *fields[FieldLast];
22
23 /* Splits fields in the line buffer by replacing TAB separators with NUL ('\0')
24 * terminators and assign these fields as pointers. If there are less fields
25 * than expected then the field is an empty string constant. */
26 void
27 parseline(char *line, char *fields[FieldLast])
28 {
29 char *prev, *s;
30 size_t i;
31
32 for (prev = line, i = 0;
33 (s = strchr(prev, '\t')) && i < FieldLast - 1;
34 ++i) {
35 *s = '\0';
36 fields[i] = prev;
37 prev = s + 1;
38 }
39 fields[i++] = prev;
40 /* make non-parsed fields empty. */
41 for (; i < FieldLast; i++)
42 fields[i] = "";
43 }
44
45 void
46 printfields(void)
47 {
48 if (!mergedfields[0].len)
49 return;
50
51 fputs(mergedfields[0].data, stdout);
52 fputs("\t", stdout);
53 fputs(mergedfields[1].data, stdout);
54 fputs("\t", stdout);
55 fputs(mergedfields[2].data, stdout);
56 fputs("\t", stdout);
57 fputs(mergedfields[3].data, stdout);
58 fputs("\t", stdout);
59 fputs(mergedfields[4].data, stdout);
60 fputs("\t", stdout);
61 fputs(mergedfields[5].data, stdout);
62 fputs("\t", stdout);
63 fputs(mergedfields[6].data, stdout);
64 fputs("\t", stdout);
65 fputs(mergedfields[7].data, stdout);
66 fputs("\n", stdout);
67 }
68
69 void
70 string_reset(struct string *d)
71 {
72 d->data[0] = '\0';
73 d->len = 0;
74 }
75
76 void
77 string_set(struct string *d, const char *data)
78 {
79 size_t len;
80
81 len = strlen(data);
82 if (len + 1 >= d->cap) {
83 d->cap = d->cap + len + 1;
84 if (!(d->data = realloc(d->data, d->cap))) {
85 perror(NULL);
86 exit(1);
87 }
88 }
89 memcpy(d->data, data, len + 1); /* copy including NUL byte */
90 d->len = len;
91 }
92
93 int
94 main(void)
95 {
96 char line[4096], *p;
97 size_t i;
98
99 /* required for Windows binary mode aka more retarded bullshit. */
100 #if WIN32
101 /* binary mode for stdin, stdout and stderr */
102 _setmode(0, 0x8000); /* 0x8000 is O_BINARY */
103 _setmode(1, 0x8000);
104 _setmode(2, 0x8000);
105 #endif
106
107 for (i = 0; i < FieldLast; ++i) {
108 mergedfields[i].cap = 4096;
109 if (!(mergedfields[i].data = calloc(1, 4096))) {
110 perror(NULL);
111 exit(1);
112 }
113 mergedfields[i].len = 0;
114 }
115
116 while (fgets(line, sizeof(line), stdin)) {
117 if ((p = strchr(line, '\n')))
118 *p = '\0';
119
120 parseline(line, fields);
121
122 /* primary key */
123 if (strcmp(fields[0], mergedfields[0].data)) {
124 printfields();
125 for (i = 0; i < FieldLast; ++i)
126 string_reset(&mergedfields[i]);
127 string_set(&mergedfields[0], fields[0]);
128 }
129
130 for (i = 1; i < FieldLast; ++i) {
131 /* field is set: override with next */
132 if (!fields[i][0])
133 continue;
134 string_set(&mergedfields[i], fields[i]);
135 }
136 }
137 printfields();
138
139 if (ferror(stdin) || (fflush(stdout) && ferror(stdout))) {
140 perror(NULL);
141 exit(1);
142 }
143
144 return 0;
145 }