The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl

($progname = $0) =~ s,.*/,,;

print "/* This file is autogenerated by $progname */\n";

print <<'EOT';

#define HCTYPE_SPACE                 0x01
#define HCTYPE_NAME_FIRST            0x02
#define HCTYPE_NAME_CHAR             0x04
#define HCTYPE_NOT_SPACE_GT          0x08
#define HCTYPE_NOT_SPACE_EQ_GT       0x10
#define HCTYPE_NOT_SPACE_SLASH_GT    0x20
#define HCTYPE_NOT_SPACE_EQ_SLASH_GT 0x40

#define HCTYPE(c)       hctype[(unsigned char)(c)]
#define isHCTYPE(c, w)  (HCTYPE(c) & (w))

#define isHSPACE(c)        isHCTYPE(c, HCTYPE_SPACE)
#define isHNAME_FIRST(c)   isHCTYPE(c, HCTYPE_NAME_FIRST)
#define isHNAME_CHAR(c)    isHCTYPE(c, HCTYPE_NAME_CHAR)
#define isHNOT_SPACE_GT(c) isHCTYPE(c, HCTYPE_NOT_SPACE_GT)

typedef unsigned char hctype_t;

EOT

print "static hctype_t hctype[] = {\n";

for my $c (0 .. 255) {
    print "    " unless $c % 8;

    local $_ = chr($c);
    my $v = 0;
    if (/^\s$/) { # isSPACE
	$v |= 0x1
    }
    elsif ($_ ne ">") {
	$v |= 0x08;
	$v |= 0x10 if $_ ne "=";
        $v |= 0x20 if $_ ne "/";
        $v |= 0x40 if $_ ne "=";
    }

    if (/^[\w.\-:]$/) {
	$v |= 0x4;
	$v |= 0x2 unless /^[\d.-]$/;  # XML allow /[:_]/ as first char
    }

    printf "0x%02x, ", $v;
    unless (($c+1) % 8) {
	printf " /* %3d - %3d */\n", $c - 7, $c;
    }
}
print "};\n";