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');
                }
        }