optimize output (unlocked), use ctype macros and force C locale - osm-zipcodes - Extract (dutch) addresses from OpenStreetMap OSM XML
(HTM) git clone git://git.codemadness.org/osm-zipcodes
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 54f22698e681ca868e9ab5453f621069edff1e25
(DIR) parent 82faa34902e3a3de1f210bb4228a645bae0279ea
(HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Tue, 12 Jul 2022 23:10:21 +0200
optimize output (unlocked), use ctype macros and force C locale
Diffstat:
M Makefile | 2 +-
M main.c | 40 +++++++++++++++++++-------------
2 files changed, 25 insertions(+), 17 deletions(-)
---
(DIR) diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
build: clean
- cc main.c -o main -O3 -Wall -static
+ cc main.c strlcpy.c strlcat.c -o main -O3 -Wall -static
strip main
clean:
(DIR) diff --git a/main.c b/main.c
@@ -4,7 +4,6 @@
#include <sys/types.h>
-#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -14,6 +13,15 @@
#include <string.h>
#include <unistd.h>
+size_t strlcat(char *dst, const char *src, size_t dsize);
+size_t strlcpy(char *dst, const char *src, size_t dsize);
+
+/* ctype-like macros, but always compatible with ASCII / UTF-8 */
+#define ISALPHA(c) ((((unsigned)c) | 32) - 'a' < 26)
+#define ISCNTRL(c) ((c) < ' ' || (c) == 0x7f)
+#define ISSPACE(c) ((c) == ' ' || ((((unsigned)c) - '\t') < 5))
+#define PUTCHAR(c) putchar_unlocked(c)
+
typedef struct xmlparser {
/* current tag */
char tag[1024];
@@ -76,7 +84,7 @@ xml_parseattrs(XMLParser *x)
int c, endsep, endname = 0, valuestart = 0;
while ((c = GETNEXT()) != EOF) {
- if (isspace(c)) {
+ if (ISSPACE(c)) {
if (namelen)
endname = 1;
continue;
@@ -86,7 +94,7 @@ xml_parseattrs(XMLParser *x)
x->name[namelen] = '\0';
valuestart = 1;
endname = 1;
- } else if (namelen && ((endname && !valuestart && isalpha(c)) || (c == '>' || c == '/'))) {
+ } else if (namelen && ((endname && !valuestart && ISALPHA(c)) || (c == '>' || c == '/'))) {
/* attribute without value */
x->name[namelen] = '\0';
xmlattr(x->tag, x->taglen, x->name, namelen, "", 0);
@@ -359,7 +367,7 @@ xml_parse(XMLParser *x)
while ((c = GETNEXT()) != EOF) {
if (c == '/')
x->isshorttag = 1; /* short tag */
- else if (c == '>' || isspace(c)) {
+ else if (c == '>' || ISSPACE(c)) {
x->tag[x->taglen] = '\0';
if (isend) { /* end tag, starts with </ */
xmltagend(x->tag, x->taglen, x->isshorttag);
@@ -368,7 +376,7 @@ xml_parse(XMLParser *x)
} else {
/* start tag */
xmltagstart(x->tag, x->taglen);
- if (isspace(c))
+ if (ISSPACE(c))
xml_parseattrs(x);
}
/* call tagend for shortform or processing instruction */
@@ -434,8 +442,8 @@ static inline void
printfield(const char *s)
{
for (; *s; s++)
- if (!iscntrl((unsigned char)*s))
- putchar(*s);
+ if (!ISCNTRL((unsigned char)*s))
+ PUTCHAR(*s);
}
/* print first zipcode, remove whitespaces (dutch format: "1234AB") */
@@ -443,8 +451,8 @@ static inline void
printzipcode(const char *s)
{
for (; *s && *s != ';'; s++)
- if (!isspace((unsigned char)*s) && !iscntrl((unsigned char)*s))
- putchar(*s);
+ if (!ISSPACE((unsigned char)*s) && !ISCNTRL((unsigned char)*s))
+ PUTCHAR(*s);
}
static inline void
@@ -459,15 +467,15 @@ printaddress(void)
/* print each housenr as a separate line */
for (s = na.housenr; s; ) {
printfield(na.id);
- putchar('\t');
+ PUTCHAR('\t');
printfield(na.lat);
- putchar('\t');
+ PUTCHAR('\t');
printfield(na.lon);
- putchar('\t');
+ PUTCHAR('\t');
printzipcode(na.postcode);
- putchar('\t');
+ PUTCHAR('\t');
printfield(na.street);
- putchar('\t');
+ PUTCHAR('\t');
/* housenr */
if ((p = strchr(s, ';'))) {
@@ -480,9 +488,9 @@ printaddress(void)
s = NULL;
}
- putchar('\t');
+ PUTCHAR('\t');
printfield(na.city);
- putchar('\n');
+ PUTCHAR('\n');
}
}