S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
{
	XML_Status status;
	
	static const int BUFFER_SIZE = 1024;
	void* buffer = NULL;	
	int count = 0;
	while (input.good() && !input.eof())
	{
		buffer = XML_GetBuffer(mParser, BUFFER_SIZE);

		/*
		 * If we happened to end our last buffer right at the end of the llsd, but the
		 * stream is still going we will get a null buffer here.  Check for mGracefullStop.
		 */
		if (!buffer)
		{
			break;
		}
		count = get_till_eol(input, (char *)buffer, BUFFER_SIZE);
		if (!count)
		{
			break;
		}
		status = XML_ParseBuffer(mParser, count, false);

		if (status == XML_STATUS_ERROR)
		{
			break;
		}
	}
	
	// *FIX.: This code is buggy - if the stream was empty or not
	// good, there is not buffer to parse, both the call to
	// XML_ParseBuffer and the buffer manipulations are illegal
	// futhermore, it isn't clear that the expat buffer semantics are
	// preserved

	status = XML_ParseBuffer(mParser, 0, true);
	if (status == XML_STATUS_ERROR && !mGracefullStop)
	{
		if (buffer)
		{
			((char*) buffer)[count ? count - 1 : 0] = '\0';
		}
		if (mEmitErrors)
		{
			LL_INFOS() << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << LL_ENDL;
		}
		data = LLSD();
		return LLSDParser::PARSE_FAILURE;
	}

	clear_eol(input);
	data = mResult;
	return mParseCount;
}
Example #2
0
static result_t*
fossil_get_info(vccontext_t *context)
{
    result_t *result = init_result();
    char *t;
    int tab_len = 14;
    char buf2[81];

    // Since fossil stores info in SQLite databases, we're going to read
    // the output of 'fossil status' command and analyze it.  We need
    // enough to cover all the usual fields (note that 'comment:' can be
    // several lines long) plus eventual output indicating changes in
    // the repo.
    char *argv[] = {"fossil", "status", NULL};
    capture_t *capture = capture_child("fossil", argv);
    if (capture == NULL) {
        debug("unable to execute 'fossil status'");
        return NULL;
    }
    char *cstdout = capture->childout.buf;

    if (context->options->show_branch) {
        if ((t = strstr(cstdout, "\ntags:"))) {
            // This in fact shows also other tags than just the
            // propagating ones (=branches).  So either we show all
            // of them (as now), or we can show only the first one
            // (which should be the branch name); or we use one more
            // child process to read the output of 'fossil branch'.
            get_till_eol(buf2, t + tab_len + 1, 80);
            debug("found tag line: '%s'", buf2);
            result_set_branch(result, buf2);
        }
        else {
            debug("tag line not found in fossil output; unknown branch");
            result_set_branch(result, "(unknown)");
        }
    }
    if (context->options->show_revision) {
        if ((t = strstr(cstdout, "\ncheckout:"))) {
            get_till_eol(buf2, t + tab_len + 1, 80);
            debug("found revision line: '%s'", buf2);
            result_set_revision(result, buf2, 12);
        }
        else {
            debug("revision line not found in fossil output; unknown revision");
            result_set_revision(result, "unknown", 7);
        }
    }
    if (context->options->show_modified) {
        // This can be also done by checking if 'fossil changes'
        // prints anything, but we save a child process this way.
        result->modified = (strstr(cstdout, "\nEDITED") ||
                            strstr(cstdout, "\nADDED") ||
                            strstr(cstdout, "\nDELETED") ||
                            strstr(cstdout, "\nMISSING") ||
                            strstr(cstdout, "\nRENAMED") ||
                            strstr(cstdout, "\nNOT_A_FILE") ||
                            strstr(cstdout, "\nUPDATED") ||
                            strstr(cstdout, "\nMERGED"));
    }

    cstdout = NULL;
    free_capture(capture);

    if (context->options->show_unknown) {
        // This can't be read from 'fossil status' output
        char *argv[] = {"fossil", "extra", NULL};
        capture = capture_child("fossil", argv);
        if (capture == NULL) {
            debug("unable to execute 'fossil extra'");
            return NULL;
        }
        result->unknown = (capture->childout.len > 0);
        free_capture(capture);
    }

    return result;
}