xml_data_node *xml_file_read(mame_file *file, xml_parse_options *opts) { xml_parse_info parse_info; int done; /* set up the parser */ if (!setup_parser(&parse_info, opts)) return NULL; /* loop through the file and parse it */ do { char tempbuf[TEMP_BUFFER_SIZE]; /* read as much as we can */ int bytes = mame_fread(file, tempbuf, sizeof(tempbuf)); done = mame_feof(file); /* parse the data */ if (XML_Parse(parse_info.parser, tempbuf, bytes, done) == XML_STATUS_ERROR) { if (opts && opts->error) { opts->error->error_message = XML_ErrorString(XML_GetErrorCode(parse_info.parser)); opts->error->error_line = XML_GetCurrentLineNumber(parse_info.parser); opts->error->error_column = XML_GetCurrentColumnNumber(parse_info.parser); } xml_file_free(parse_info.rootnode); XML_ParserFree(parse_info.parser); return NULL; } } while (!done); /* free the parser */ XML_ParserFree(parse_info.parser); /* return the root node */ return parse_info.rootnode; }
/**************************************************************************** * GetNextToken - Pointer to the token string pointer * Pointer to position within file * * Returns token, or TOKEN_INVALID if at end of file ****************************************************************************/ static UINT32 GetNextToken(char **ppszTokenText, long *pdwPosition) { UINT32 dwLength; /* Length of symbol */ long dwPos; /* Temporary position */ UINT8 *pbTokenPtr = bToken; /* Point to the beginning */ UINT8 bData; /* Temporary data byte */ while (1) { bData = mame_fgetc(fp); /* Get next character */ /* If we're at the end of the file, bail out */ if (mame_feof(fp)) return(TOKEN_INVALID); /* If it's not whitespace, then let's start eating characters */ if (' ' != bData && '\t' != bData) { /* Store away our file position (if given on input) */ if (pdwPosition) *pdwPosition = dwFilePos; /* If it's a separator, special case it */ if (',' == bData || '=' == bData) { *pbTokenPtr++ = bData; *pbTokenPtr = '\0'; ++dwFilePos; if (',' == bData) return(TOKEN_COMMA); else return(TOKEN_EQUALS); } /* Otherwise, let's try for a symbol */ if (bData > ' ') { dwLength = 0; /* Assume we're 0 length to start with */ /* Loop until we've hit something we don't understand */ while (bData != ',' && bData != '=' && bData != ' ' && bData != '\t' && bData != '\n' && bData != '\r' && mame_feof(fp) == 0) { ++dwFilePos; *pbTokenPtr++ = bData; /* Store our byte */ ++dwLength; assert(dwLength < MAX_TOKEN_LENGTH); bData = mame_fgetc(fp); } /* If it's not the end of the file, put the last received byte */ /* back. We don't want to touch the file position, though if */ /* we're past the end of the file. Otherwise, adjust it. */ if (0 == mame_feof(fp)) { mame_ungetc(bData, fp); } /* Null terminate the token */ *pbTokenPtr = '\0'; /* Connect up the */ if (ppszTokenText) *ppszTokenText = (char *)bToken; return(TOKEN_SYMBOL); } /* Not a symbol. Let's see if it's a cr/cr, lf/lf, or cr/lf/cr/lf */ /* sequence */ if (LF == bData) { /* Unix style perhaps? */ bData = mame_fgetc(fp); /* Peek ahead */ mame_ungetc(bData, fp); /* Force a retrigger if subsequent LF's */ if (LF == bData) /* Two LF's in a row - it's a UNIX hard CR */ { ++dwFilePos; *pbTokenPtr++ = bData; /* A real linefeed */ *pbTokenPtr = '\0'; return(TOKEN_LINEBREAK); } /* Otherwise, fall through and keep parsing. */ } else if (CR == bData) /* Carriage return? */ { /* Figure out if it's Mac or MSDOS format */ ++dwFilePos; bData = mame_fgetc(fp); /* Peek ahead */ /* We don't need to bother with EOF checking. It will be 0xff if */ /* it's the end of the file and will be caught by the outer loop. */ if (CR == bData) /* Mac style hard return! */ { /* Do not advance the file pointer in case there are successive */ /* CR/CR sequences */ /* Stuff our character back upstream for successive CR's */ mame_ungetc(bData, fp); *pbTokenPtr++ = bData; /* A real carriage return (hard) */ *pbTokenPtr = '\0'; return(TOKEN_LINEBREAK); } else if (LF == bData) /* MSDOS format! */ { ++dwFilePos; /* Our file position to reset to */ dwPos = dwFilePos; /* Here so we can reposition things */ /* Look for a followup CR/LF */ bData = mame_fgetc(fp); /* Get the next byte */ if (CR == bData) /* CR! Good! */ { bData = mame_fgetc(fp); /* Get the next byte */ /* We need to do this to pick up subsequent CR/LF sequences */ mame_fseek(fp, dwPos, SEEK_SET); if (pdwPosition) *pdwPosition = dwPos; if (LF == bData) /* LF? Good! */ { *pbTokenPtr++ = '\r'; *pbTokenPtr++ = '\n'; *pbTokenPtr = '\0'; return(TOKEN_LINEBREAK); } } else { --dwFilePos; mame_ungetc(bData, fp); /* Put the character back. No good */ } } else { --dwFilePos; mame_ungetc(bData, fp); /* Put the character back. No good */ } /* Otherwise, fall through and keep parsing */ } } ++dwFilePos; } }