|  | #include "test-tool.h" | 
|  |  | 
|  | static const char *utf8_replace_character = "�"; | 
|  |  | 
|  | /* | 
|  | * Encodes (possibly incorrect) UTF-8 on <stdin> to <stdout>, to be embedded | 
|  | * in an XML file. | 
|  | */ | 
|  | int cmd__xml_encode(int argc, const char **argv) | 
|  | { | 
|  | unsigned char buf[1024], tmp[4], *tmp2 = NULL; | 
|  | ssize_t cur = 0, len = 1, remaining = 0; | 
|  | unsigned char ch; | 
|  |  | 
|  | for (;;) { | 
|  | if (++cur == len) { | 
|  | len = xread(0, buf, sizeof(buf)); | 
|  | if (!len) | 
|  | return 0; | 
|  | if (len < 0) | 
|  | die_errno("Could not read <stdin>"); | 
|  | cur = 0; | 
|  | } | 
|  | ch = buf[cur]; | 
|  |  | 
|  | if (tmp2) { | 
|  | if ((ch & 0xc0) != 0x80) { | 
|  | fputs(utf8_replace_character, stdout); | 
|  | tmp2 = NULL; | 
|  | cur--; | 
|  | continue; | 
|  | } | 
|  | *tmp2 = ch; | 
|  | tmp2++; | 
|  | if (--remaining == 0) { | 
|  | fwrite(tmp, tmp2 - tmp, 1, stdout); | 
|  | tmp2 = NULL; | 
|  | } | 
|  | continue; | 
|  | } | 
|  |  | 
|  | if (!(ch & 0x80)) { | 
|  | /* 0xxxxxxx */ | 
|  | if (ch == '&') | 
|  | fputs("&", stdout); | 
|  | else if (ch == '\'') | 
|  | fputs("'", stdout); | 
|  | else if (ch == '"') | 
|  | fputs(""", stdout); | 
|  | else if (ch == '<') | 
|  | fputs("<", stdout); | 
|  | else if (ch == '>') | 
|  | fputs(">", stdout); | 
|  | else if (ch >= 0x20) | 
|  | fputc(ch, stdout); | 
|  | else if (ch == 0x09 || ch == 0x0a || ch == 0x0d) | 
|  | fprintf(stdout, "&#x%02x;", ch); | 
|  | else | 
|  | fputs(utf8_replace_character, stdout); | 
|  | } else if ((ch & 0xe0) == 0xc0) { | 
|  | /* 110XXXXx 10xxxxxx */ | 
|  | tmp[0] = ch; | 
|  | remaining = 1; | 
|  | tmp2 = tmp + 1; | 
|  | } else if ((ch & 0xf0) == 0xe0) { | 
|  | /* 1110XXXX 10Xxxxxx 10xxxxxx */ | 
|  | tmp[0] = ch; | 
|  | remaining = 2; | 
|  | tmp2 = tmp + 1; | 
|  | } else if ((ch & 0xf8) == 0xf0) { | 
|  | /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */ | 
|  | tmp[0] = ch; | 
|  | remaining = 3; | 
|  | tmp2 = tmp + 1; | 
|  | } else | 
|  | fputs(utf8_replace_character, stdout); | 
|  | } | 
|  |  | 
|  | return 0; | 
|  | } |