#include /* fprintf(3), getc(3), putc(3) stderr, stdin, EOF */ #include /* strchr(3) */ #include "ascii.h" /* ASCII_HEXADECIMAL_DIGITS_LOWER, * ASCII_HEXADECIMAL_DIGITS_UPPER */ #include "libunicode.h" /* utf8(3) */ static struct { char *name; utf32_t (*f)(utf32_t); } static char *hex = ASCII_HEXADECIMAL_DIGITS_UPPER ASCII_HEXADECIMAL_DIGITS_LOWER; int main(int argc, char *argv[]){ int c; int i; int l; /* line counter */ char *n; utf32_t codepoint; utf8_t encoded; l = 0; init: codepoint = 0; i = 0; ++l; n = NULL; while((c = getc(stdin)) != EOF){ if(c == '\n'){ if(i < 2 && i > 0) /* empty lines are fine */ fprintf(stderr, "%s: %s: Syntax error.\n", argv[0], l); else if(i >= 2){ encoded = utf8(codepoint); for(i = 3; i >= 0; --i) if((encoded >> 8 * i) > 0 || i == 0) putc(encoded >> 8 * i, stdout); } goto init; } if( (i == 0 && c != 'U') || (i == 1 && c != '+') || i > 8 /* strlen("U+10FFFF") */ || (i > 1 && ((n = strchr(hex, c)) == NULL)) ){ fprintf(stderr, "%s: %s: Syntax error.\n", argv[0], l); while((c = getc(stdin)) != '\n' && c != EOF); ++l; continue; } if(n != NULL) codepoint = (codepoint << 4) + (n - hex) % 16; ++i; } }