1b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project#define CHARSET_MAX 41 2b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project 3b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectstatic const char * 4b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source ProjectgetTok(const char **pp) 5b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{ 6b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project enum { inAtom, inString, init, inComment }; 7b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project int state = init; 8b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project const char *tokStart = 0; 9b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project for (;;) { 10b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project switch (**pp) { 11b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case '\0': 12b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return 0; 13b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case ' ': 14b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case '\r': 15b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case '\t': 16b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case '\n': 17b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (state == inAtom) 18b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return tokStart; 19b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 20b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case '(': 21b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (state == inAtom) 22b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return tokStart; 23b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (state != inString) 24b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project state++; 25b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 26b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case ')': 27b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (state > init) 28b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project --state; 29b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project else if (state != inString) 30b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return 0; 31b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 32b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case ';': 33b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case '/': 34b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case '=': 35b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (state == inAtom) 36b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return tokStart; 37b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (state == init) 38b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return (*pp)++; 39b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 40b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case '\\': 41b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project ++*pp; 42b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (**pp == '\0') 43b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return 0; 44b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 45b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case '"': 46b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project switch (state) { 47b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case inString: 48b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project ++*pp; 49b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return tokStart; 50b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case inAtom: 51b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return tokStart; 52b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project case init: 53b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project tokStart = *pp; 54b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project state = inString; 55b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 56b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 57b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 58b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project default: 59b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (state == init) { 60b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project tokStart = *pp; 61b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project state = inAtom; 62b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 63b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 64b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 65b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project ++*pp; 66b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 67b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project /* not reached */ 68b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project} 69b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project 70b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project/* key must be lowercase ASCII */ 71b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project 72b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectstatic int 73b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectmatchkey(const char *start, const char *end, const char *key) 74b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{ 75b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (!start) 76b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return 0; 77b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project for (; start != end; start++, key++) 78b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (*start != *key && *start != 'A' + (*key - 'a')) 79b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return 0; 80b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return *key == '\0'; 81b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project} 82b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project 83b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectvoid 84b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source ProjectgetXMLCharset(const char *buf, char *charset) 85b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{ 86b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project const char *next, *p; 87b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project 88b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project charset[0] = '\0'; 89b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project next = buf; 90b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project p = getTok(&next); 91b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (matchkey(p, next, "text")) 92b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project strcpy(charset, "us-ascii"); 93b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project else if (!matchkey(p, next, "application")) 94b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return; 95b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project p = getTok(&next); 96b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (!p || *p != '/') 97b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return; 98b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project p = getTok(&next); 99b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (matchkey(p, next, "xml")) 100b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project isXml = 1; 101b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project p = getTok(&next); 102b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project while (p) { 103b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (*p == ';') { 104b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project p = getTok(&next); 105b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (matchkey(p, next, "charset")) { 106b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project p = getTok(&next); 107b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (p && *p == '=') { 108b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project p = getTok(&next); 109b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (p) { 110b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project char *s = charset; 111b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (*p == '"') { 112b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project while (++p != next - 1) { 113b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (*p == '\\') 114b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project ++p; 115b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (s == charset + CHARSET_MAX - 1) { 116b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project charset[0] = '\0'; 117b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 118b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 119b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project *s++ = *p; 120b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 121b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project *s++ = '\0'; 122b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 123b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project else { 124b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project if (next - p > CHARSET_MAX - 1) 125b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 126b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project while (p != next) 127b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project *s++ = *p++; 128b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project *s = 0; 129b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project break; 130b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 131b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 132b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 133b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 134b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 135b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project else 136b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project p = getTok(&next); 137b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project } 138b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project} 139b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project 140b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectint 141b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Projectmain(int argc, char **argv) 142b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project{ 143b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project char buf[CHARSET_MAX]; 144b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project getXMLCharset(argv[1], buf); 145b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project printf("charset = \"%s\"\n", buf); 146b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project return 0; 147b80e287d54a028e744f9fe412840a89ec7f8084bThe Android Open Source Project} 148