latest with zcurve
[handlerosm.git] / osmsucker.c
blobe6dfa469e09e811c6b86f76d140c6cce9921c5bf
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/mman.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <fcntl.h>
7 #include <string.h>
8 #include <errno.h>
9 #include <math.h>
10 #include <unistd.h>
13 * <osm>
14 * <node>
15 * <tag k=".." v=".." />
16 * </node>
17 * <way>
18 * <nd>
19 * <tag>
20 * </way>
21 * <relation>
22 * <member>
23 * <tag>
24 * </relation>
27 #ifdef MMAP
28 # define stopcondition (start = ++end) < (range + max)
29 # define nextline start = end + 1
30 #else
31 # define nextline free(start); start = NULL; tmp = getline(&start, &tmplen, stdin); if (tmp == -1) { goto exit; }
32 # define stopcondition 1
33 #endif
36 #define file_nodes "nodes.csv"
38 #ifdef BENCHMARK
39 #define file_nodes_uint "nodes_uint.csv"
40 #define file_nodes_gis "nodes_gis.csv"
41 #endif
43 #define file_node_tags "node_tags.csv"
44 #define file_ways "ways.csv"
45 #define file_way_tags "way_tags.csv"
46 #define file_way_nds "way_nds.csv"
47 #define file_relations "relations.csv"
48 #define file_relation_tags "relation_tags.csv"
49 #define file_relation_member_node "relation_member_node.csv"
50 #define file_relation_member_relation "relation_member_relation.csv"
51 #define file_relation_member_way "relation_member_way.csv"
53 unsigned int coordtouint(char *input) {
54 double maxbit = (double) 4294967296.0 / (double) 360.0;
55 double proper = strtod(input, NULL) * maxbit;
56 return (unsigned int) proper;
59 char * escape_string(char *instr)
61 unsigned int i, j=0, need = 0;
62 unsigned int len = strlen(instr);
63 char *outstr;
65 for (i=0;i<len;i++)
66 if (instr[i]=='\\' || instr[i]=='\'') need++;
68 len += need;
69 outstr = malloc(len + 1);
71 for (i=0;i<=strlen(instr);i++) {
72 if (instr[i]=='\\' || instr[i]=='\'')
73 outstr[j++]='\\';
74 outstr[j++]=instr[i];
76 return outstr;
79 #ifdef MMAP
80 static void parser(char *range, unsigned long int max) {
81 #else
82 static void parser() {
83 #endif
84 typedef enum { OSM = 0, NODE = 1, WAY = 2, RELATION = 3, TAG = 4, ND = 5, MEMBER = 6 } osm_state_t;
85 typedef enum { UNKNOWN = 0, ID, LAT, LON, USER, UID, TIMESTAMP, KEY, VALUE, TYPE, REF, ROLE} key_state_t;
86 char *attr_id = NULL, *attr_lat = NULL, *attr_lon = NULL, *attr_user = NULL, *attr_uid = NULL, *attr_timestamp = NULL, *attr_key = NULL, *attr_value = NULL,
87 *attr_type = NULL, *attr_ref = NULL, *attr_role = NULL;
89 unsigned int attr_lat_uint = 0;
90 unsigned int attr_lon_uint = 0;
92 FILE *fd_nodes = fopen(file_nodes, "w");
93 if (fd_nodes == NULL) { perror("Open:"); exit(-1); }
94 #ifdef BENCHMARK
95 FILE *fd_nodes_uint = fopen(file_nodes_uint, "w");
96 if (fd_nodes_uint == NULL) { perror("Open:"); exit(-1); }
97 FILE *fd_nodes_gis = fopen(file_nodes_gis, "w");
98 if (fd_nodes_gis == NULL) { perror("Open:"); exit(-1); }
99 #endif
100 FILE *fd_node_tags = fopen(file_node_tags, "w");
101 if (fd_node_tags == NULL) { perror("Open:"); exit(-1); }
102 FILE *fd_ways = fopen(file_ways, "w");
103 if (fd_ways == NULL) { perror("Open:"); exit(-1); }
104 FILE *fd_way_tags = fopen(file_way_tags, "w");
105 if (fd_way_tags == NULL) { perror("Open:"); exit(-1); }
106 FILE *fd_way_nds = fopen(file_way_nds, "w");
107 if (fd_way_nds == NULL) { perror("Open:"); exit(-1); }
108 FILE *fd_relations = fopen(file_relations, "w");
109 if (fd_relations == NULL) { perror("Open:"); exit(-1); }
110 FILE *fd_relation_tags = fopen(file_relation_tags, "w");
111 if (fd_relation_tags == NULL) { perror("Open:"); exit(-1); }
112 FILE *fd_members_node = fopen(file_relation_member_node, "w");
113 if (fd_members_node == NULL) { perror("Open:"); exit(-1); }
114 FILE *fd_members_relation = fopen(file_relation_member_relation, "w");
115 if (fd_members_relation == NULL) { perror("Open:"); exit(-1); }
116 FILE *fd_members_way = fopen(file_relation_member_way, "w");
117 if (fd_members_way == NULL) { perror("Open:"); exit(-1); }
119 unsigned long int count_nodes = 0, count_node_tags = 0,
120 count_ways = 0, count_way_tags = 0, count_way_nds = 0,
121 count_relations = 0, count_relation_tags = 0, count_members_node = 0, count_members_relation = 0, count_members_way = 0;
123 unsigned long int sequence = 0;
126 osm_state_t current_tag = OSM;
127 osm_state_t parent_tag = OSM;
129 char *start = NULL, *end, *nodename, *nodename_end;
130 ssize_t tmp;
131 size_t tmplen = 0;
133 #ifdef MMAP
134 start = range;
135 #else
136 nextline;
137 #endif
138 end = strchrnul((const char*) start, '\n');
140 if (strncmp(start, "<?xml", 5) != 0)
141 return;
143 nextline;
144 end = strchrnul((const char*) start, '\n');
146 if (strncmp(start, "<osm", 4) != 0)
147 return;
149 nextline;
151 do {
152 end = strchrnul((const char*) start, '\n');
154 nodename = strchrnul(start, '<') + 1;
155 nodename_end = strchrnul(nodename, ' ');
157 if (nodename[0] == '/') {
158 free(attr_id);
159 free(attr_lat);
160 free(attr_lon);
161 free(attr_timestamp);
162 free(attr_user);
163 free(attr_uid);
165 attr_id = attr_lat = attr_lon = attr_user = attr_uid = attr_timestamp = NULL;
167 sequence = 0;
169 nextline;
170 continue;
173 switch (nodename_end - nodename) {
174 case 2:
175 current_tag = ND;
176 break;
177 case 3: {
178 switch (nodename[0]) {
179 case 'o':
180 current_tag = OSM;
181 break;
182 case 'w':
183 current_tag = WAY;
184 break;
185 case 't':
186 current_tag = TAG;
187 break;
188 default:
189 fprintf(stderr, "--> %c%c", nodename[0], nodename[1]);
191 break;
193 case 4:
194 current_tag = NODE;
195 break;
196 case 5:
197 /* BOUND */
198 nextline;
199 continue;
200 case 6:
201 current_tag = MEMBER;
202 break;
203 case 8:
204 current_tag = RELATION;
205 break;
206 default:
207 fprintf(stderr, "--> %c%c", nodename[0], nodename[1]);
211 char *key, *key_end, *value_end;
212 key = nodename_end + 1;
214 do {
215 char *value;
216 key_state_t current_key = UNKNOWN;
217 key_end = strchrnul(key, '=');
219 if (key_end == NULL || key_end >= end)
220 break;
222 switch (key_end - key) {
223 case 1: {
224 switch (key[0]) {
225 case 'k':
226 current_key = KEY;
227 break;
228 case 'v':
229 current_key = VALUE;
230 break;
231 default:
232 current_key = UNKNOWN;
234 break;
236 case 2:
237 current_key = ID;
238 break;
239 case 3: {
240 switch (key[1]) {
241 case 'a':
242 current_key = LAT;
243 break;
244 case 'o':
245 current_key = LON;
246 break;
247 case 'e':
248 current_key = REF;
249 break;
250 case 'i':
251 current_key = UID;
252 break;
253 default:
254 current_key = UNKNOWN;
255 fprintf(stderr, "--> %c%c\n", key[0], key[1]);
257 break;
259 case 4: {
260 switch (key[0]) {
261 case 'u':
262 current_key = USER;
263 break;
264 case 'r':
265 current_key = ROLE;
266 break;
267 case 't':
268 current_key = TYPE;
269 break;
270 default:
271 current_key = UNKNOWN;
272 fprintf(stderr, "--> %c%c\n", key[0], key[1]);
274 break;
276 case 9:
277 current_key = TIMESTAMP;
278 break;
279 default: {
280 char *thingie = strndup(key, (key_end - key));
281 current_key = UNKNOWN;
283 fprintf(stderr, "UNKNOWN ATTR %s-> %c%c\n", thingie, key[0], key[1]);
284 free(thingie);
288 value = key_end + 2;
289 value_end = value;
290 value_end = strchr(value_end, '"');
292 if (value_end > end)
293 break;
295 switch (current_key) {
296 case ID:
297 if (attr_id) free(attr_id);
298 attr_id = strndup(value, (value_end - value));
299 break;
301 case LAT:
302 if (attr_lat) free(attr_lat);
303 attr_lat = strndup(value, (value_end - value));
304 attr_lat_uint = coordtouint(attr_lat);
305 break;
307 case LON:
308 if (attr_lon) free(attr_lon);
309 attr_lon = strndup(value, (value_end - value));
310 attr_lon_uint = coordtouint(attr_lon);
311 break;
313 case TIMESTAMP:
314 if (attr_timestamp) free(attr_timestamp);
315 // attr_timestamp = strndup(value, (value_end - value));
316 attr_timestamp = strndup(value, (value_end - (value + 1))); /* another stupid fix */
317 // attr_timestamp[10] = ' '; /* Stupid timestamp fix */
318 break;
320 case USER: {
321 char *tmp;
322 if (attr_user) free(attr_user);
323 attr_user = strndup(value, (value_end - value));
324 tmp = escape_string(attr_user);
325 free(attr_user);
326 attr_user = tmp;
327 break;
330 case UID: {
331 if (attr_uid) free(attr_uid);
332 attr_uid = strndup(value, (value_end - value));
333 break;
336 case KEY: {
337 char *tmp;
338 if (attr_key) free(attr_key);
339 attr_key = strndup(value, (value_end - value));
340 tmp = escape_string(attr_key);
341 free(attr_key);
342 attr_key = tmp;
343 break;
346 case VALUE: {
347 char *tmp;
348 if (attr_value) free(attr_value);
349 attr_value = strndup(value, (value_end - value));
350 tmp = escape_string(attr_value);
351 free(attr_value);
352 attr_value = tmp;
353 break;
356 case TYPE:
357 if (attr_type) free(attr_type);
358 attr_type = strndup(value, (value_end - value));
359 break;
361 case REF:
362 if (attr_ref) free(attr_ref);
363 attr_ref = strndup(value, (value_end - value));
364 break;
366 case ROLE: {
367 char *tmp;
368 if (attr_role) free(attr_role);
369 attr_role = strndup(value, (value_end - value));
370 tmp = escape_string(attr_role);
371 free(attr_role);
372 attr_role = tmp;
373 break;
376 default:
377 fprintf(stderr, "--> %c%c\n", value[0], value[1]);
380 key = value_end + 2;
381 } while (key < end);
383 switch (current_tag) {
384 case NODE:
385 fprintf(fd_nodes, "%s, %s, %s, %s, '%s'\n", attr_id, attr_lat, attr_lon, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp);
386 #ifdef BENCHMARK
387 fprintf(fd_nodes_uint, "%s, %d, %d, %s, '%s'\n", attr_id, attr_lat_uint, attr_lon_uint, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp);
388 fprintf(fd_nodes_gis, "%s, 'POINT( %s %s )', '%s', '%s'\n", attr_id, attr_lon, attr_lat, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp);
389 #endif
390 count_nodes++;
391 break;
392 case TAG: {
393 switch (parent_tag) {
394 case NODE:
395 fprintf(fd_node_tags, "%s, '%s', '%s'\n", attr_id, attr_key, attr_value);
396 count_node_tags++;
397 break;
398 case WAY:
399 fprintf(fd_way_tags, "%s, '%s', '%s'\n", attr_id, attr_key, attr_value);
400 count_way_tags++;
401 break;
402 case RELATION:
403 fprintf(fd_relation_tags, "%s, '%s', '%s'\n", attr_id, attr_key, attr_value);
404 count_relation_tags++;
405 break;
406 default:
407 break;
409 break;
411 case WAY:
412 fprintf(fd_ways, "%s, %s, '%s'\n", attr_id, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp);
413 count_ways++;
414 // fprintf(fd_way_tags, "%s, '%s', '%s'\n", attr_id, "type", "way");
415 // count_way_tags++;
416 break;
417 case RELATION:
418 fprintf(fd_relations, "%s, %s, '%s'\n", attr_id, (attr_uid != NULL ? attr_uid : "0"), attr_timestamp);
419 count_relations++;
420 break;
421 case MEMBER:
422 if (strcmp(attr_type, "node") == 0) {
423 fprintf(fd_members_node, "%s, %lu, %s, '%s'\n", attr_id, sequence, attr_ref, attr_role);
424 count_members_node++;
425 } else if (strcmp(attr_type, "way") == 0) {
426 fprintf(fd_members_way, "%s, %lu, %s, '%s'\n", attr_id, sequence, attr_ref, attr_role);
427 count_members_way++;
428 } else if (strcmp(attr_type, "relation") == 0) {
429 fprintf(fd_members_relation, "%s, %lu, %s, '%s'\n", attr_id, sequence, attr_ref, attr_role);
430 count_members_relation++;
432 sequence++;
433 break;
434 case ND:
435 fprintf(fd_way_nds, "%s, %lu, %s\n", attr_id, sequence, attr_ref);
436 sequence++;
437 count_way_nds++;
438 break;
439 default:
440 break;
443 if (end[-2] == '/') {
444 switch (current_tag) {
445 case NODE:
446 free(attr_lat);
447 free(attr_lon);
448 attr_lat = NULL;
449 attr_lon = NULL;
450 attr_lat_uint = 0;
451 attr_lon_uint = 0;
452 /* no break! */
454 case WAY:
455 case RELATION:
456 free(attr_id);
457 free(attr_timestamp);
458 free(attr_user);
459 free(attr_uid);
461 attr_id = attr_user = attr_uid = attr_timestamp = NULL;
463 sequence = 0;
464 break;
466 case TAG:
467 free(attr_key);
468 free(attr_value);
470 attr_key = NULL;
471 attr_value = NULL;
472 break;
474 case ND:
475 case MEMBER:
476 free(attr_type);
477 free(attr_ref);
478 free(attr_role);
480 attr_type = NULL;
481 attr_ref = NULL;
482 attr_role = NULL;
483 default:
484 break;
486 } else if (current_tag == NODE || current_tag == WAY || current_tag == RELATION) {
487 parent_tag = current_tag;
491 nextline;
492 } while (stopcondition);
493 exit:
495 free(attr_id);
496 free(attr_lat);
497 free(attr_lon);
498 free(attr_timestamp);
499 free(attr_user);
500 free(attr_uid);
502 free(attr_key);
503 free(attr_value);
505 fclose(fd_nodes);
506 #ifdef BENCHMARK
507 fclose(fd_nodes_uint);
508 fclose(fd_nodes_gis);
509 #endif
510 fclose(fd_node_tags);
511 fclose(fd_ways);
512 fclose(fd_way_tags);
513 fclose(fd_way_nds);
514 fclose(fd_relations);
515 fclose(fd_relation_tags);
516 fclose(fd_members_node);
517 fclose(fd_members_relation);
518 fclose(fd_members_way);
520 char *current = get_current_dir_name();
522 printf("START TRANSACTION;\n");
524 printf("CREATE TABLE nodes_legacy (id integer, long double, lat double, uid integer, timestamp timestamptz);\n");
525 #ifdef BENCHMARK
526 printf("CREATE TABLE nodes_legacy_uint (id integer, long integer, lat integer, uid integer, timestamp timestamptz);\n");
527 printf("CREATE TABLE nodes_legacy_gis (id integer, poi point, uid integer, timestamp timestamptz);\n");
528 #endif
529 printf("CREATE TABLE node_tags (node integer, k varchar(255), v varchar(1024));\n");
530 printf("CREATE TABLE ways (id integer,uid integer, timestamp timestamptz);\n");
531 printf("CREATE TABLE way_tags (way integer, k varchar(255), v varchar(1024));\n");
532 printf("CREATE TABLE way_nds (way integer, idx integer, to_node integer);\n");
533 printf("CREATE TABLE relations(id integer, uid integer, timestamp timestamptz);\n");
534 printf("CREATE TABLE relation_members_node (relation integer, idx integer, to_node integer, role varchar(255));\n");
535 printf("CREATE TABLE relation_members_relation (relation integer, idx integer, to_relation integer, role varchar(255));\n");
536 printf("CREATE TABLE relation_members_way (relation integer, idx integer, to_way integer, role varchar(255));\n");
537 printf("CREATE TABLE relation_tags (relation integer, k varchar(255), v varchar(1024));\n");
539 printf("COPY %lu RECORDS INTO nodes_legacy from '%s/" file_nodes "' USING DELIMITERS ',', '\\n', '''';\n", count_nodes, current);
540 #ifdef BENCHMARK
541 printf("COPY %lu RECORDS INTO nodes_legacy_uint from '%s/" file_nodes_uint "' USING DELIMITERS ',', '\\n', '''';\n", count_nodes, current);
542 printf("COPY %lu RECORDS INTO nodes_legacy_gis from '%s/" file_nodes_gis "' USING DELIMITERS ',', '\\n', '''';\n", count_nodes, current);
543 #endif
544 printf("COPY %lu RECORDS INTO node_tags from '%s/" file_node_tags "' USING DELIMITERS ',', '\\n', '''';\n", count_node_tags, current);
545 printf("COPY %lu RECORDS INTO ways from '%s/" file_ways "' USING DELIMITERS ',', '\\n', '''';\n", count_ways, current);
546 printf("COPY %lu RECORDS INTO way_tags from '%s/" file_way_tags "' USING DELIMITERS ',', '\\n', '''';\n", count_way_tags, current);
547 printf("COPY %lu RECORDS INTO way_nds from '%s/" file_way_nds "' USING DELIMITERS ',', '\\n', '''';\n", count_way_nds, current);
548 printf("COPY %lu RECORDS INTO relations from '%s/" file_relations "' USING DELIMITERS ',', '\\n', '''';\n", count_relations, current);
549 printf("COPY %lu RECORDS INTO relation_tags from '%s/" file_relation_tags "' USING DELIMITERS ',', '\\n', '''';\n", count_relation_tags, current);
550 printf("COPY %lu RECORDS INTO relation_members_node from '%s/" file_relation_member_node "' USING DELIMITERS ',', '\\n', '''';\n", count_members_node, current);
551 printf("COPY %lu RECORDS INTO relation_members_relation from '%s/" file_relation_member_relation "' USING DELIMITERS ',', '\\n', '''';\n", count_members_relation, current);
552 printf("COPY %lu RECORDS INTO relation_members_way from '%s/" file_relation_member_way "' USING DELIMITERS ',', '\\n', '''';\n", count_members_way, current);
554 printf("COMMIT;\n");
556 printf("START TRANSACTION;\n");
558 printf("CREATE SEQUENCE s_nodes AS INTEGER;\n");
559 printf("ALTER SEQUENCE s_nodes RESTART WITH (SELECT MAX(id) FROM nodes_legacy);\n");
560 printf("ALTER TABLE nodes_legacy ALTER COLUMN id SET NOT NULL;\n");
561 printf("ALTER TABLE nodes_legacy ALTER COLUMN id SET DEFAULT NEXT VALUE FOR \"sys\".\"s_nodes\";\n");
562 printf("ALTER TABLE nodes_legacy ADD CONSTRAINT pk_nodes_id PRIMARY KEY (id);\n");
564 printf("CREATE SEQUENCE s_ways AS INTEGER;\n");
565 printf("ALTER SEQUENCE s_ways RESTART WITH (SELECT MAX(id) FROM ways);\n");
566 printf("ALTER TABLE ways ALTER COLUMN id SET NOT NULL;\n");
567 printf("ALTER TABLE ways ALTER COLUMN id SET DEFAULT NEXT VALUE FOR \"sys\".\"s_ways\";\n");
568 printf("ALTER TABLE ways ADD CONSTRAINT pk_ways_id PRIMARY KEY (id);\n");
570 printf("CREATE SEQUENCE s_relations AS INTEGER;\n");
571 printf("ALTER SEQUENCE s_relations RESTART WITH (SELECT MAX(id) FROM relations);\n");
572 printf("ALTER TABLE relations ALTER COLUMN id SET NOT NULL;\n");
573 printf("ALTER TABLE relations ALTER COLUMN id SET DEFAULT NEXT VALUE FOR \"sys\".\"s_relations\";\n");
574 printf("ALTER TABLE relations ADD CONSTRAINT pk_relations_id PRIMARY KEY (id);\n");
576 printf("ALTER TABLE relation_members_node ADD CONSTRAINT pk_relation_members_node PRIMARY KEY (relation, idx);\n");
577 printf("ALTER TABLE relation_members_way ADD CONSTRAINT pk_relation_members_way PRIMARY KEY (relation,idx);\n");
578 printf("ALTER TABLE relation_members_relation ADD CONSTRAINT pk_relation_members_relation PRIMARY KEY (relation,idx);\n");
580 printf("COMMIT;\n");
583 printf("START TRANSACTION;\n");
585 printf("ALTER TABLE node_tags ADD CONSTRAINT pk_node_tags PRIMARY KEY (node, k);\n");
586 printf("ALTER TABLE node_tags ADD CONSTRAINT fk_node_tags_node FOREIGN KEY (node) REFERENCES nodes_legacy (id);\n");
588 printf("ALTER TABLE way_tags ADD CONSTRAINT pk_way_tags PRIMARY KEY (way, k);\n");
589 printf("ALTER TABLE way_tags ADD CONSTRAINT fk_way_tags_way FOREIGN KEY (way) REFERENCES ways (id);\n");
591 printf("ALTER TABLE way_nds ADD CONSTRAINT pk_way_nds PRIMARY KEY (way, idx);\n");
592 printf("ALTER TABLE way_nds ADD CONSTRAINT fk_way_nds_way FOREIGN KEY (way) REFERENCES ways (id);\n");
593 printf("ALTER TABLE way_nds ADD CONSTRAINT fk_way_nds_node FOREIGN KEY (to_node) REFERENCES nodes_legacy (id);\n");
595 printf("ALTER TABLE relation_tags ADD CONSTRAINT pk_relation_tags PRIMARY KEY (relation, k);\n");
596 printf("ALTER TABLE relation_tags ADD CONSTRAINT fk_relation_tags FOREIGN KEY (relation) REFERENCES relations (id);\n");
598 printf("ALTER TABLE relation_members_node ADD CONSTRAINT fk_relation_members_node FOREIGN KEY (relation) REFERENCES relations (id);\n");
599 printf("ALTER TABLE relation_members_node ADD CONSTRAINT fk_relation_members_tonode FOREIGN KEY (to_node) REFERENCES nodes_legacy (id);\n");
601 printf("ALTER TABLE relation_members_way ADD CONSTRAINT fk_relation_members_way FOREIGN KEY (relation) REFERENCES relations (id);\n");
602 printf("ALTER TABLE relation_members_way ADD CONSTRAINT fk_relation_members_toway FOREIGN KEY (to_way) REFERENCES ways (id);\n");
604 printf("ALTER TABLE relation_members_relation ADD CONSTRAINT fk_relation_members_relation FOREIGN KEY (relation) REFERENCES relations (id);\n");
605 printf("ALTER TABLE relation_members_relation ADD CONSTRAINT fk_relation_members_torelation FOREIGN KEY (to_relation) REFERENCES relations (id);\n");
607 printf("COMMIT;\n");
609 free(current);
614 int main(int argc, char *argv[]) {
615 #ifdef MMAP
616 int fd;
617 struct stat statbuf;
619 if (argc != 2)
620 exit(-1);
622 fprintf(stderr, "Analysing %s...\n", argv[1]);
624 fd = open(argv[1], O_RDONLY);
626 if (fd < 0)
627 exit(-1);
629 if (fstat (fd, &statbuf) == -1) { perror("fstat:"); exit(-1); }
631 if (statbuf.st_size > 0) {
632 char *range = NULL;
633 range = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, (off_t) 0);
634 if (range == MAP_FAILED) { perror("Mmap:"); printf("(did you compile PAE in the kernel?)\n"); exit(-1); }
635 parser(range, statbuf.st_size / sizeof(char));
636 munmap(range, statbuf.st_size);
639 close(fd);
640 #else
641 parser();
642 #endif
643 exit(0);