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