/** Tokenize data. */ TokenNode *Tokenize(const char *line, const char *fileName) { AttributeNode *ap; TokenNode *current; char *temp; unsigned int x; unsigned int offset; unsigned int lineNumber; char inElement; char found; head = NULL; current = NULL; inElement = 0; lineNumber = 1; x = 0; /* Skip any initial white space. */ while(IsSpace(line[x], &lineNumber)) { x += 1; } /* Skip any XML stuff. */ if(!strncmp(line + x, "<?", 2)) { while(line[x]) { if(line[x] == '\n') { lineNumber += 1; } if(!strncmp(line + x, "?>", 2)) { x += 2; break; } x += 1; } } /* Process the XML data. */ while(line[x]) { /* Skip comments and white space. */ do { /* Skip white space. */ while(IsSpace(line[x], &lineNumber)) { x += 1; } /* Skip comments */ found = 0; if(!strncmp(line + x, "<!--", 4)) { while(line[x]) { if(line[x] == '\n') { lineNumber += 1; } if(!strncmp(line + x, "-->", 3)) { x += 3; found = 1; break; } x += 1; } } } while(found); switch(line[x]) { case '<': x += 1; if(line[x] == '/') { /* Close tag. */ x += 1; temp = ReadElementName(line + x); if(current) { if(JLIKELY(temp)) { if(JUNLIKELY(current->type != LookupType(temp, NULL))) { Warning(_("%s[%u]: close tag \"%s\" does not " "match open tag \"%s\""), fileName, lineNumber, temp, GetTokenName(current)); } } else { Warning(_("%s[%u]: unexpected and invalid close tag"), fileName, lineNumber); } current = current->parent; } else { if(temp) { Warning(_("%s[%u]: close tag \"%s\" without open tag"), fileName, lineNumber, temp); } else { Warning(_("%s[%u]: invalid close tag"), fileName, lineNumber); } } if(temp) { x += strlen(temp); Release(temp); } } else { /* Open tag. */ current = CreateNode(current, fileName, lineNumber); temp = ReadElementName(line + x); if(JLIKELY(temp)) { x += strlen(temp); LookupType(temp, current); Release(temp); } else { Warning(_("%s[%u]: invalid open tag"), fileName, lineNumber); } } inElement = 1; break; case '/': /* End of open/close tag. */ if(inElement) { x += 1; if(JLIKELY(line[x] == '>' && current)) { x += 1; current = current->parent; inElement = 0; } else { Warning(_("%s[%u]: invalid tag"), fileName, lineNumber); } } else { goto ReadDefault; } break; case '>': /* End of open tag. */ x += 1; inElement = 0; break; default: ReadDefault: if(inElement) { /* In the open tag; read attributes. */ ap = CreateAttribute(current); ap->name = ReadElementName(line + x); if(ap->name) { x += strlen(ap->name); if(line[x] == '=') { x += 1; } if(line[x] == '\"') { x += 1; } ap->value = ReadAttributeValue(line + x, fileName, &offset, &lineNumber); x += offset; if(line[x] == '\"') { x += 1; } } } else { /* In tag body; read text. */ temp = ReadElementValue(line + x, fileName, &offset, &lineNumber); x += offset; if(temp) { if(current) { if(current->value) { current->value = Reallocate(current->value, strlen(current->value) + strlen(temp) + 1); strcat(current->value, temp); Release(temp); } else { current->value = temp; } } else { if(JUNLIKELY(temp[0])) { Warning(_("%s[%u]: unexpected text: \"%s\""), fileName, lineNumber, temp); } Release(temp); } } } break; } } return head; }
/** Tokenize a data. */ TokenNode *Tokenize(const char *line, const char *fileName) { TokenNode *np; AttributeNode *ap; char *temp; int inElement; int x; int found; int lineNumber; head = NULL; current = NULL; inElement = 0; lineNumber = 1; x = 0; /* Skip any initial white space */ while(IsSpace(line[x], &lineNumber)) ++x; /* Skip any XML stuff */ if(!strncmp(line + x, "<?", 2)) { while(line[x]) { if(line[x] == '\n') { ++lineNumber; } if(!strncmp(line + x, "?>", 2)) { x += 2; break; } ++x; } } while(line[x]) { do { while(IsSpace(line[x], &lineNumber)) ++x; /* Skip comments */ found = 0; if(!strncmp(line + x, "<!--", 4)) { while(line[x]) { if(line[x] == '\n') { ++lineNumber; } if(!strncmp(line + x, "-->", 3)) { x += 3; found = 1; break; } ++x; } } } while(found); switch(line[x]) { case '<': ++x; if(line[x] == '/') { ++x; temp = ReadElementName(line + x); if(current) { if(temp) { if(current->type != LookupType(temp, NULL)) { Warning("%s[%d]: close tag \"%s\" does not " "match open tag \"%s\"", fileName, lineNumber, temp, GetTokenName(current)); } } else { Warning("%s[%d]: unexpected and invalid close tag", fileName, lineNumber); } current = current->parent; } else { if(temp) { Warning("%s[%d]: close tag \"%s\" without open " "tag", fileName, lineNumber, temp); } else { Warning("%s[%d]: invalid close tag", fileName, lineNumber); } } if(temp) { x += strlen(temp); Release(temp); } } else { np = current; current = NULL; np = CreateNode(np, fileName, lineNumber); temp = ReadElementName(line + x); if(temp) { x += strlen(temp); LookupType(temp, np); Release(temp); } else { Warning("%s[%d]: invalid open tag", fileName, lineNumber); } } inElement = 1; break; case '/': if(inElement) { ++x; if(line[x] == '>' && current) { ++x; current = current->parent; inElement = 0; } else { Warning("%s[%d]: invalid tag", fileName, lineNumber); } } else { goto ReadDefault; } break; case '>': ++x; inElement = 0; break; default: ReadDefault: if(inElement) { ap = CreateAttribute(current); ap->name = ReadElementName(line + x); if(ap->name) { x += strlen(ap->name); if(line[x] == '=') { ++x; } if(line[x] == '\"') { ++x; } ap->value = ReadAttributeValue(line + x, fileName, &lineNumber); if(ap->value) { x += strlen(ap->value); } if(line[x] == '\"') { ++x; } } } else { temp = ReadElementValue(line + x, fileName, &lineNumber); if(temp) { x += strlen(temp); if(current) { if(current->value) { current->value = Reallocate(current->value, strlen(current->value) + strlen(temp) + 1); strcat(current->value, temp); Release(temp); } else { current->value = temp; } } else { if(temp[0]) { Warning("%s[%d]: unexpected text: \"%s\"", fileName, lineNumber, temp); } Release(temp); } } } break; } } return head; }