Пример #1
1
Font::Font(QString image_path, QString xml_path)
{
    QFile f(xml_path);
    QString errorStr("");
    int errorLine(0);
    int errorColumn(0);
    QDomDocument doc;
    QDomElement root;
    
    if (!f.open(QFile::ReadOnly | QFile::Text)) {
        qCritical("ERROR: Failed to open config file \"%s\": %s",
                  xml_path.toUtf8().constData(),
                  f.errorString().toUtf8().constData()
                  );
        return;
    }
    
    if (!doc.setContent(&f, false, &errorStr, &errorLine, &errorColumn)) {
        qCritical("ERROR: Failed to parse config file \"%s\" at line %d, column %d:\n%s",
                  xml_path.toUtf8().constData(),
                  errorLine,
                  errorColumn,
                  errorStr.toUtf8().constData()
                  );
        return;
    }
    
    root = doc.documentElement();
    if (root.tagName() != "Font") {
        qCritical("ERROR: Unexpected root element \"%s\" at line %d, column %d",
                  root.tagName().toUtf8().constData(),
                  root.lineNumber(),
                  root.columnNumber());
        return;
    }
    
    this->size = root.attribute("size").toInt();
    this->family = root.attribute("family");
    this->height = root.attribute("height").toInt();
    this->style = root.attribute("style");
    
//    qDebug("Font: %d, %s, %d, %s", this->size, this->family.toUtf8().constData(), this->height, this->style.toUtf8().constData());
    
    _minChar = 127;
    _maxChar = 0;
    QDomElement childElement = root.firstChildElement();
    while (!childElement.isNull()) {
        QString tagName = childElement.tagName();
        if (tagName == "Char") {
            Char *c = new Char(childElement);
            this->_chars[c->code] = c;
            if (c->code > _maxChar)
                _maxChar = c->code;
            if (c->code < _minChar)
                _minChar = c->code;
        }
        childElement = childElement.nextSiblingElement();
    }
    
    QImageReader image_reader(image_path);
    this->_image = image_reader.read();
}
Пример #2
0
    //Simple systemc thread which keeps on generating interrupts;
    //the number of the interrupt is printed to the screen before sending it to
    //the processor
    void generateIrq() {
        while(true) {

            //An interrupt transaction is composed of a data pointer (containing
            //0 if the interrupt has to be lowered, different if raised) and an
            //address, corrisponding to the ID of the interrupt
            if(this->lastIrq == -1) {
                unsigned char data = 1;
                tlm::tlm_generic_payload trans;
                boost::uniform_int<> degen_dist(0x1, 0xe);
                boost::variate_generator<boost::minstd_rand&, boost::uniform_int<> > deg(this->generator, degen_dist);
                this->lastIrq = deg();
                std::cerr << "Sending out IRQ id=" << std::hex << std::showbase << this->lastIrq << std::endl;
                trans.set_address(this->lastIrq);
                trans.set_data_ptr(&data);
                trans.set_data_length(0);
                trans.set_byte_enable_ptr(0);
                trans.set_dmi_allowed(false);
                trans.set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );
                sc_time delay;
                this->init_socket->b_transport(trans, delay);

                if(trans.is_response_error()) {
                    std::string errorStr("Error in generateIrq, response status = " + trans.get_response_string());
                    SC_REPORT_ERROR("TLM-2", errorStr.c_str());
                }
            }
            wait(this->latency);
        }
    }
Пример #3
0
    //Method used for receiving acknowledgements of interrupts; the ack consists of
    //uninteresting data and the address corresponds to the interrupt signal to
    //be lowered
    //As a response, I lower the interrupt by sending a NULL pointer on the init_socket
    void b_transport(tlm::tlm_generic_payload& trans, sc_time& delay) {
        if(this->lastIrq < 0) {
            THROW_EXCEPTION("Error, lowering an interrupt which hasn't been raised yet!!");
        }
        tlm::tlm_command cmd = trans.get_command();
        sc_dt::uint64    adr = trans.get_address();
        unsigned char*   ptr = trans.get_data_ptr();
        if(trans.get_command() == tlm::TLM_READ_COMMAND) {
            THROW_EXCEPTION("Error, the read request is not currently supported by external PINs");
        }
        else if(cmd == tlm::TLM_WRITE_COMMAND) {
            if(this->lastIrq != adr) {
                THROW_EXCEPTION("Error, lowering interrupt " << std::hex << std::showbase << (unsigned)adr << " while " << std::hex << std::showbase << this->lastIrq << " was raised");
            }
            else {
                //finally I can really lower the interrupt: I send 0 on
                //the initSocked
                unsigned char data = 0;
                trans.set_data_ptr(&data);
                trans.set_dmi_allowed(false);
                trans.set_response_status( tlm::TLM_INCOMPLETE_RESPONSE );
                sc_time delay;
                this->init_socket->b_transport(trans, delay);
                if(trans.is_response_error()) {
                    std::string errorStr("Error in b_transport of PIN, response status = " + trans.get_response_string());
                    SC_REPORT_ERROR("TLM-2", errorStr.c_str());
                }

                this->lastIrq = -1;
            }
        }

        trans.set_response_status(tlm::TLM_OK_RESPONSE);
    }
Пример #4
0
void
VETypeList::DoNoCPPbSupportDialog(
	ConstStringPtr	inFileName )
{
	StApplicationContext	appContext;
	StDialogHandler			dialog(PPob_NoCPPbSupport, LCommander::GetTopCommander());
	
	// make the error string
	
	LStr255 errorStr(STRx_NoCPPbSupport, NoCPPb_StringFirst);
	if ( inFileName[0] > 0 ) {
		errorStr += inFileName;
	}
	errorStr += LStr255(STRx_NoCPPbSupport, NoCPPb_StringSecond);
	
	LStaticText *theCaption = dynamic_cast<LStaticText *> (dialog.GetDialog()->FindPaneByID(NoCPPb_Caption));
	theCaption->SetDescriptor(errorStr);
			
	dialog.GetDialog()->Show();
	
	MessageT theMessage;
	do {
		theMessage = dialog.DoDialog();
	} while ( (theMessage != msg_OK) && (theMessage != msg_Cancel) );

	LCommander::SetUpdateCommandStatus(true);
}
Пример #5
0
base::FileStatus HdfsFile::stat()
{
    if(!configured_) {
        throw std::runtime_error("Need to configure first");
    }

    if (!fileStatCache_->contains(filename_)) {
        char *error = NULL;
        webhdfs_fstat_t *stat = webhdfs_stat(fs_, filename_.c_str(), &error);
        if(stat == NULL) {
            std::string errorStr(error);
            if (error) {
                free(error);
            }
            throw std::runtime_error(errorStr);
        }
        base::FileStatus s;
        s.blockSize = stat->block;
        s.length = stat->length;
        s.replicationFactor = stat->replication;
        webhdfs_fstat_free(stat);

        fileStatCache_->set(filename_, s);
    }

    return boost::any_cast<base::FileStatus>(fileStatCache_->get(filename_));
}
Пример #6
0
void Flashlight::setEnabled(bool newState)
{
    Q_D(Flashlight);

    if (d->camHandle == CAMERA_HANDLE_INVALID) {
        qDebug("Flashlight error: invalid camera handle");
        return;
    }

    auto lightMode = CAMERA_VIDEOLIGHT_OFF;

    if (newState) {
        lightMode = CAMERA_VIDEOLIGHT_ON;
    }

    auto err = camera_config_videolight(d->camHandle, lightMode);

    d->lightOn = !d->lightOn;
    if (err != CAMERA_EOK) {
        auto action = "disabling";

        if (newState) {
            action = "enabling";
        }
        qDebug("Flashlight error: failed to %s flashlight: %s", action, errorStr(err).c_str());
    }
}
/// @return >0 for FD, -1 means error.
int CorosyncCpg::getFd() {
  int fd = -1;
  cs_error_t cs;
  if (ready && handle != 0 && CS_OK != (cs = cpg_fd_get(handle, &fd))) {
    LOG(ERROR)<< errorStr(cs, "Cannot get CPG file descriptor");
    return -1;
  }
  return fd;
}
Пример #8
0
void Widget::ftpCommandFinished(int, bool error)
{
    int id = ftp->currentCommand();
    QString errorStr(ftp->errorString());
    if(id == QFtp::ConnectToHost)
    {
        if(error)
            qDebug() << tr("连接到服务器出现错误:%1").arg(errorStr);
        else
            qDebug() << tr("连接到服务器成功");
    }
    else if(id == QFtp::Login)
    {
        if(error)
            qDebug() << tr("登录出现错误:%1").arg(errorStr);
        else
        {
            qDebug() << tr("登录成功");
            ui->fileListTreeWidget->setEnabled(true);
            ui->downloadPushButton->setEnabled(true);
            clearAndAddCdParentItem();
            ftp->list();
        }
    }
    else if(id == QFtp::Get)
    {
        if(error)
            qDebug() << tr("下载出现错误:%1").arg(errorStr);
        else
        {
            qDebug() << tr("已经完成下载");
            file->close();
//            ui->textBrowser->setText(ftp->readAll());            
        }
//        ui->downloadPushButton->setEnabled(true);
    }
    else if(id == QFtp::Close)
    {
        if(error)
            qDebug() << tr("关闭连接出现错误:%1").arg(errorStr);
        else
            qDebug() << tr("已经关闭连接");
    }    
    else if(id == QFtp::List)
    {
        if(isDirectory.isEmpty())
        {
//            ui->fileListTreeWidget->addTopLevelItem(
//                        new QTreeWidgetItem(QStringList()<<tr("<empty>")));
//            ui->fileListTreeWidget->setEnabled(false);
            qDebug() << tr("该目录为空");
        }
    }
    else
        qDebug() << "ftpCommandFinished() if else";
    return;
}
Пример #9
0
void PrintError(const wxString& msg, int err) {
	char errbuf[128];
	const char *errbuf_ptr = errbuf;
	
	if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
		errbuf_ptr = strerror(AVUNERROR(err));
	wxString errorStr(errbuf_ptr, wxConvUTF8);
	wxLogError(msg + wxT(": ") + errorStr);
}
Пример #10
0
void JagunMSNConnection::addContact(QString loginAdd, QString message)
{
    if (!logged)
    {
        return;
    }

    qDebug() << "JagunMSNConnection :: adicionando contato " << userLogin << " - " << loginAdd << "  -  " << message;
    db.createNewConnection();
    if ( ! db.searchUser(loginAdd)  )
    {
        if ( db.checkContacts(userLogin,loginAdd) || db.checkContacts(loginAdd, userLogin) )
        {
            db.addContact(userLogin,loginAdd,message);
            quint32 idConnectionContact = db.getIdConnection(loginAdd);
            JagunMSNConnection *connectionContact = getOtherConnection(idConnectionContact);
            if (connectionContact)
            {
                QString xml = parserToXML.requestAddContact(userLogin,message);
                QByteArray messageSend;
                messageSend.append(xml);
                connectionContact->send(&messageSend);
            }
        } else {
            qDebug() << "JagunMSNConnection :: ja estava adicionado";
            JagunMSNContact *contact = db.getData(loginAdd);
            JagunMSNContact *user    = db.getData(userLogin);

            QString xml = parserToXML.changeStatusContact(contact->getLogin(),contact->getNickname(),
                                                          contact->getMessage(),contact->getImage(), (int) contact->getStatus());
            QByteArray messageSend;
            messageSend.append(xml);
            send(&messageSend);

            quint32 idConnectionContact = db.getIdConnection(loginAdd);
            JagunMSNConnection *connectionContact = getOtherConnection(idConnectionContact);

            if (connectionContact)
            {
                qDebug() << "JagunMSNConnection :: outro online";
                QString xmlTo = parserToXML.changeStatusContact(user->getLogin(), user->getNickname(),
                                                               user->getMessage(), user->getImage(), (int) user->getStatus() );
                QByteArray messageSendTo;
                messageSendTo.append(xmlTo);
                connectionContact->send(&messageSendTo);
            }
        }
    } else {
        QString errorStr(tr("Usuário não existe"));
        QString xml = parserToXML.addContactError(errorStr);
        QByteArray messageSend;
        messageSend.append(xml);
        send(&messageSend);
    }
    //db.closeConnection();
}
Пример #11
0
void JagunMSNConnection::loginUser(QString login, QString password)
{
    qDebug() << "JagunMSNConnection :: logando usuario";
    //db.createNewConnection();
    QString xml;
    if ( db.loginUser(login, password) )
    {
        qDebug() << "JagunMSNConnection :: usuario on";
        //Logado
        // pega os ultimos dados do usuario e armazena o id da conexao
        db.setIdConnection(login, getIdConnection());
        JagunMSNContact *userData = db.getData(login);

        QString nickname = userData->getNickname();
        QString message  = userData->getMessage();
        QString image    = userData->getImage();
        int status       = (int) userData->getLastStatus();
        if ( status == (int) JagunMSNContact::ECSOffline  ) {
            status = (int) JagunMSNContact::ECSOnline;
        }

        xml = parserToXML.logOn(login,nickname,message,image,status);

        logged     = true;
        userLogin  = login;
        userStatus = status;
    } else {
        qDebug() << "JagunMSNConnection :: usuario error";
        // Erro
        QString errorStr(tr("Login ou Senha inválida"));
        xml = parserToXML.loginUserError(errorStr);
    }

    QByteArray messageSend;
    messageSend.append(xml);
    send(&messageSend);

    if (logged) {
        JagunMSNContact *userData = db.getData(login);

        QString nickname = userData->getNickname();
        QString message  = userData->getMessage();
        QString image    = userData->getImage();
        int status       = (int) userData->getLastStatus();
        if ( status == (int) JagunMSNContact::ECSOffline  ) {
            status = (int) JagunMSNContact::ECSOnline;
        }
        QStringList sendToo;

        sendAllRequestAddContact();
        changeStatus(nickname,message,image,status,sendToo);
    } else {
        close();
    }
    //db.closeConnection();
}
Пример #12
0
FlashlightPrivate::~FlashlightPrivate()
{
    if (camHandle != CAMERA_HANDLE_INVALID) {
        auto error = camera_close(camHandle);

        if (error != CAMERA_EOK) {
            qDebug("Failed to close camera: %s.", errorStr(error).c_str());
        }
    }
}
Пример #13
0
void Log::LogWarn(logLevel level, const char* logMessage, const char* file, int line)
{
    Glib::ustring errorStr(logMessage);
    time_t raw_time;
    
    time(&raw_time);

    switch(level){
        case LEVEL_LOG_ERROR:
            Log::errorDialog->set_default_response(GTK_RESPONSE_OK);
            Log::errorDialog->set_secondary_text(errorStr);
            if(errno != 0)
                Log::errorDialog->set_message(strerror(errno));
            Log::errorDialog->run();
            Log::errorDialog->hide();
            errorStr.append(" in file ");
            errorStr.append(file); errorStr.append(" in line ");
            errorStr.append(std::to_string(line));
            writeMessageLogFile (asctime(gmtime(&raw_time)) << ": ERROR " << strerror(errno) << "! ", logMessage, file, line);
            writeMessageTerminal(asctime(gmtime(&raw_time)) << ": ERROR " << strerror(errno) << "! ", logMessage, file, line);
            errno = 0; /* resets errno to zero */
            exit(1);
            break;
        case LEVEL_LOG_WARNING:
            Log::warnDialog->set_default_response(GTK_RESPONSE_OK);
            Log::warnDialog->set_secondary_text(errorStr);
            if(errno != 0)
                Log::warnDialog->set_message(strerror(errno));
            Log::warnDialog->run();
            Log::warnDialog->hide();
            errorStr.append(" in file ");
            errorStr.append(file); errorStr.append(" in line ");
            errorStr.append(std::to_string(line)); 
            writeMessageLogFile (asctime(gmtime(&raw_time)) << ": WARNING " << strerror(errno) << "! ", logMessage, file, line);
            writeMessageTerminal(asctime(gmtime(&raw_time)) << ": WARNING " << strerror(errno) << "! ", logMessage, file, line);
            errno = 0; /* Resets errno to zero */
            break;
        case LEVEL_LOG_INFO:
            Log::infoDialog->set_default_response(GTK_RESPONSE_OK);
            Log::infoDialog->set_secondary_text(errorStr);
            Log::infoDialog->run();
            Log::infoDialog->hide();
            writeMessageLogFile (asctime(gmtime(&raw_time)) << ": INFO ", logMessage, file, line);
            writeMessageTerminal(asctime(gmtime(&raw_time)) << ": INFO ", logMessage, file, line);
            break;
        case LEVEL_LOG_SILENT:
            writeMessageLogFile (asctime(gmtime(&raw_time)) << ": INFO ", logMessage, file, line);
            writeMessageTerminal(asctime(gmtime(&raw_time)) << ": INFO ", logMessage, file, line);
            break;
        default:
            *(Log::logFile) << "Error message not found ! Please repport this incident in the Issue Tracker at github" << std::endl;
            exit(1);
    }
}
Пример #14
0
FlashlightPrivate::FlashlightPrivate()
  : camHandle { CAMERA_HANDLE_INVALID },
    lightOn { false }
{
    auto error = camera_open(CAMERA_UNIT_REAR, CAMERA_MODE_PREAD | CAMERA_MODE_PWRITE, &camHandle);

     if (error == CAMERA_EOK) {
         auto hasLight = camera_can_feature(camHandle, CAMERA_FEATURE_VIDEOLIGHT);

         if (!hasLight) {
             qDebug("Flashlight error: video light not available.");
             error = camera_close(camHandle);
             if (error != CAMERA_EOK) {
                 qDebug("Flashlight error: failed to close camera: %s.", errorStr(error).c_str());
             }
             camHandle = CAMERA_HANDLE_INVALID;
         }
     } else {
         qDebug("Flashlight error: failed to open camera: %s.", errorStr(error).c_str());
     }
}
Пример #15
0
/*static*/ v8::Handle<v8::Value> wxNodeObject::extendCallHandler(const v8::Arguments& args) {
  v8::HandleScope scope;
  v8::Local<v8::Object> result;

  v8::Local<v8::Object> argsData = args.Data()->ToObject();
  v8::Handle<v8::Object> baseClass = argsData->Get(v8::String::New("baseClass"))->ToObject();
  v8::Handle<v8::Object> subClass = argsData->Get(v8::String::New("subClass"))->ToObject();

  // create new object
  v8::Local<v8::Value> argv[0];
  result = v8::Object::Cast(*baseClass->CallAsConstructor(0, argv));

  v8::Function* superWrapMethod = v8::Function::Cast(*v8::Context::GetCurrent()->Global()->Get(v8::String::New("__superWrapMethod")));

  // copy subClass methods
  v8::Local<v8::Array> subClassPropNames = subClass->GetPropertyNames();
  for(uint32_t i=0; i<subClassPropNames->Length(); i++) {
    v8::Local<v8::String> propName = subClassPropNames->Get(i)->ToString();
    v8::Local<v8::Value> propVal = subClass->Get(propName);
    v8::Local<v8::Value> basePropVal = result->Get(propName);

    if(propVal->IsFunction()) {
      v8::Local<v8::Value> superWrapArgv[2];
      superWrapArgv[0] = propVal;
      superWrapArgv[1] = basePropVal;
      propVal = superWrapMethod->Call(result, 2, superWrapArgv);
      result->Set(propName, propVal);
    } else {
      result->Set(propName, propVal);
    }
  }

  // call init
  int argc = args.Length();
  v8::Handle<v8::Value>* initArgs = new v8::Handle<v8::Value>[argc];
  for(int i=0; i<argc; i++) {
    initArgs[i] = args[i];
  }
  v8::Local<v8::Value> initObj = result->Get(v8::String::New("init"));

  v8::Function *initFn = v8::Function::Cast(*initObj);

  v8::TryCatch tryCatch;
  initFn->Call(result, argc, initArgs);
  if(tryCatch.HasCaught()) {
    v8::String::AsciiValue errorStr(tryCatch.Exception());
    printf("%s\n", *errorStr);
    return scope.Close(tryCatch.Exception()); // TODO: causes Seg fault
  }

  return scope.Close(result);
}
Пример #16
0
void EtherApp::CheckLinkStatus(GLuint program) {
	GLint isLinked = 0;
	glGetProgramiv(program, GL_LINK_STATUS, &isLinked);

	GLint  maxLength = 0;
	glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);

	if (maxLength > 0) {
		std::vector<GLchar> errorLog(maxLength);
		glGetProgramInfoLog(program, maxLength, &maxLength, &errorLog[0]);
		std::string errorStr(errorLog.begin(), errorLog.end());

		EtherLog::GetInstance()->LogError(errorStr);
	}
}
JParseResult
JParseAsNumericVariable
	(
	const JCharacter*		origExpr,
	const JSize				origLength,
	const JVariableList*	theVariableList,
	JFunction**				theFunction,
	const JBoolean			allowUIF
	)
{
	*theFunction = NULL;

	// remove enclosing parentheses

	const JCharacter* expr = origExpr;
	const JSize length     = JStripParentheses(&expr, origLength);

	// try to parse the expression as a single variable

	JIndex varIndex;
	JFunction* arrayIndex = NULL;

	const JParseResult result = JParseVariable(expr, length, theVariableList,
											   &varIndex, &arrayIndex, allowUIF);

	if (result == kJParsedOK && !theVariableList->IsNumeric(varIndex))
		{
		delete arrayIndex;

		JString errorStr(expr, length);
		errorStr.Prepend("\"");
		errorStr += "\" is not a numeric variable";
		(JGetUserNotification())->ReportError(errorStr);
		return kJParseError;
		}
	else if (result == kJParsedOK)
		{
		*theFunction = new JVariableValue(theVariableList, varIndex, arrayIndex);
		assert( *theFunction != NULL );
		return kJParsedOK;
		}
	else
		{
		return result;
		}
}
Пример #18
0
/***********************************************************
call lua function
***********************************************************/
std::string LuaHandlerBase::CallLua(const std::string & functioname, ScriptEnvironmentBase* env)
{
    try
    {
        if(env)
            luabind::call_function<void>(m_LuaState, functioname.c_str(), env);
        else
            luabind::call_function<void>(m_LuaState, functioname.c_str());
    }
    catch(const std::exception &error)
    {
        std::string errorStr("Exception calling lua function ");
        errorStr += functioname + std::string(" : ") + error.what() + std::string(" : ") + lua_tostring(m_LuaState, -1);
        LogHandler::getInstance()->LogToFile(errorStr, 0);
        return errorStr;
    }
    return "Success";
}
Пример #19
0
void HdfsFile::configure(base::ConfigurationMap &conf) {
    GET_PARAMETER(hdfsConfigurationFile_, std::string, "hdfsConfigurationFile");

    try {
        overwrite_ = boost::any_cast<bool>(conf["overwrite"]);
    }
    catch(...) {
        // PASS
        //LOG(INFO) << "overwrite not specified. Defaulting to false";
    }

    /* Setup webhdfs config */
    DLOG(INFO) << "Reading HDFS config: " << hdfsConfigurationFile_;

    char *error = NULL;
    conf_ = webhdfs_conf_load(hdfsConfigurationFile_.c_str(), &error);
    if(!conf_) {
        std::ostringstream os;
        os << "Error reading hdfs config: " << hdfsConfigurationFile_ << " : ";
        std::string errorStr(os.str());
        if (error) {
            errorStr += std::string(error);
            free(error);
        }
        throw std::runtime_error(errorStr);
    }

    /* Connect to WebHDFS */
    fs_ = webhdfs_connect(conf_);
    if(!fs_) {
        throw std::runtime_error("error in webhdfs_connect");
    }

    f_ = webhdfs_file_open(fs_, filename_.c_str());

    if(!f_) {
        throw std::runtime_error("error in webhdfs_file_open");
    }

    GET_PARAMETER(fileStatCache_, boost::shared_ptr<base::Cache>, "fileStatCache");

    configured_ = true;
}
ConfigFileParser::ConfigFileParser(const std::string filename) : 
		FILENAME(filename), PARSERS(fillParsers()) {
	
	foundCutter = foundStock = foundPoints = false;
	
	std::ifstream ifs;
	FileUtils::openFile(filename, ifs);
	
	while(ifs.good() && !foundAll()) {
		std::string str = FileUtils::readNextValidLine(ifs).validLine;
		
		// checks if given line is a section string of type: [SMTHNG]
		boost::smatch matcher;
		boost::regex expression("\\[(\\w+)\\]");
		if (!boost::regex_match(str, matcher, expression)) {
			abortParsing("'" + str + "' is not a valid section");
		}
		std::string section(matcher[1]);
		
		ParsersMap::const_iterator it;
		it = PARSERS.find(section);
		if (it == PARSERS.end()) {
			// no parsers registered to dissect given section
			abortParsing("unknown section '" + section + "'");
		}
		
		// invoke parser in order to dissect section
		(this->*(it->second))(ifs);
		
		// then continue to the next section
	}
	
	if (!foundAll()) {
		std::string errorStr("missing section[s]: ");
		if (!foundCutter)
			errorStr += "tool ";
		if (!foundPoints)
			errorStr += "point ";
		if (!foundStock)
			errorStr += "product ";
		abortParsing(errorStr);
	}
}
Пример #21
0
void EtherApp::CompileShader(GLuint shader, const std::string& shaderPath) {
	std::string assetsDir = EtherPlatform::GetInstance()->GetAssetsDirectory();
	if (assetsDir.empty()) {
		return;
	}

	std::string tmpShaderPath = assetsDir + "shaders/" + shaderPath;
	std::string shaderString;
	std::ifstream sourceFile(tmpShaderPath.c_str());

	if (sourceFile) {
		shaderString.assign((std::istreambuf_iterator< char >(sourceFile)), std::istreambuf_iterator< char >());
	}
	else {
		std::stringstream ss;
		ss << "Error loading file contents from " << shaderPath << std::endl;
		EtherLog::GetInstance()->LogError(ss.str());
		return;
	}

	const GLchar* shaderSource = shaderString.c_str();

	// load/compile shader
	glShaderSource(shader, 1, (const GLchar**)&shaderSource, NULL);
	glCompileShader(shader);

	GLint isCompiled = 0;

	glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);

	GLint maxLength = 0;
	glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);

	if(maxLength > 0) {
		std::vector<GLchar> errorLog(maxLength);
		glGetShaderInfoLog(shader, maxLength, &maxLength, &errorLog[0]);
		std::string errorStr(errorLog.begin(), errorLog.end());

		EtherLog::GetInstance()->LogError(errorStr);
	}
}
bool QstProtocol::waitForConnected( int timeout )
{
    QTime t;
    t.start();
    bool ok = false;
    QTime t2;
    t2.start();
    while (t.elapsed() < timeout && !ok) {
        ok = QTcpSocket::waitForConnected(timeout);
        if (!ok) {
            wait(100);
            if (t2.elapsed() > 1000) {
                t2.start();
                reconnect();
            }
        }
    }

    if (ok) {
        if (debug_on) {
            qDebug() << QString("%1 QstProtocol::waitForConnected(%2, %3) ...")
                        .arg(uniqueId()).arg(timeout).arg(stateStr()).toLatin1();
        }
        t2.start();
        while (t.elapsed() < timeout && !isConnected()) {
            wait(10);
            if (!isConnected() && t2.elapsed() > 500) {
                postMessage( QstMessage(QLatin1String("QTEST_NEW_CONNECTION")) );
                t2.start();
            }
        }
        ok = isConnected();
    }

    if (debug_on) {
        qDebug() << QString("%1 QstProtocol::waitForConnected() ... %2 (%3 ms)").arg(uniqueId()).arg(ok ? "OK" : "FAILED" ).arg(t.elapsed()).toLatin1();
        if (!ok) qDebug() << errorStr();
    }
    return ok;
}
Пример #23
0
void AnimationReader::run() {
    DependencyManager::get<StatTracker>()->decrementStat("PendingProcessing");
    CounterStat counter("Processing");

    PROFILE_RANGE_EX(resource_parse, __FUNCTION__, 0xFF00FF00, 0, { { "url", _url.toString() } });
    auto originalPriority = QThread::currentThread()->priority();
    if (originalPriority == QThread::InheritPriority) {
        originalPriority = QThread::NormalPriority;
    }
    QThread::currentThread()->setPriority(QThread::LowPriority);
    try {
        if (_data.isEmpty()) {
            throw QString("Reply is NULL ?!");
        }
        QString urlname = _url.path().toLower();
        bool urlValid = true;
        urlValid &= !urlname.isEmpty();
        urlValid &= !_url.path().isEmpty();

        if (urlValid) {
            // Parse the FBX directly from the QNetworkReply
            HFMModel::Pointer hfmModel;
            if (_url.path().toLower().endsWith(".fbx")) {
                hfmModel = FBXSerializer().read(_data, QVariantHash(), _url.path());
            } else {
                QString errorStr("usupported format");
                emit onError(299, errorStr);
            }
            emit onSuccess(hfmModel);
        } else {
            throw QString("url is invalid");
        }

    } catch (const QString& error) {
        emit onError(299, error);
    }
    QThread::currentThread()->setPriority(originalPriority);
}
Пример #24
0
void JagunMSNConnection::newUser(QString login, QString password, QString email)
{
    qDebug() << "JagunMSNConnection :: criando nova conta";
    //db.createNewConnection();
    QString xml;
    if ( db.insertNewUser(login,email,password) ) {
        // Conta criada
        qDebug() << "JagunMSNConnection :: conta criada";
        QDateTime date = QDateTime::currentDateTime();
        xml = parserToXML.userCreated(login,date);
    } else {
        //Conta nao criada
        qDebug() << "JagunMSNConnection :: conta nao criada";
        QString errorStr( tr("Não foi possível criar conta") );
        xml = parserToXML.userNotCreated(errorStr);
    }

    QByteArray message;
    message.append(xml);
    send(&message);

    //db.closeConnection();
    close();
}
JBoolean
JRecurseDecision
	(
	const JCharacter*		origExpr,
	const JSize				origLength,
	const JVariableList*	theVariableList,
	JDecision**				theDecision
	)
{
	*theDecision = NULL;

	// remove enclosing parentheses

	const JCharacter* expr = origExpr;
	const JSize length     = JStripParentheses(&expr, origLength);

	if (length == 0)
		{
		(JGetUserNotification())->ReportError("You specified an empty decision");
		return kJFalse;
		}

	// check for a constant

	if (JIsBoolConstant(expr, length, theDecision))
		{
		return kJTrue;
		}

	// search for an operator

	JDecisionType type;
	JSize start,end;

	if (JContainsBooleanOperator(expr, length, &type, &start, &end))
		{
		JDecision* arg1 = NULL;
		JDecision* arg2 = NULL;

		if (!JRecurseDecision(expr, start, theVariableList, &arg1) ||
			!JRecurseDecision(expr + end, length - end, theVariableList, &arg2))
			{
			delete arg1;
			delete arg2;
			return kJFalse;
			}

		if (type == kJBooleanANDType)
			{
			*theDecision = new JBooleanAND(arg1, arg2);
			}
		else if (type == kJBooleanORType)
			{
			*theDecision = new JBooleanOR(arg1, arg2);
			}
		else if (type == kJBooleanXORType)
			{
			*theDecision = new JBooleanXOR(arg1, arg2);
			}
		else
			{
			cerr << "JRecurseDecision:  unknown boolean operator" << endl;
			delete arg1;
			delete arg2;
			return kJFalse;
			}
		assert( *theDecision != NULL );
		return kJTrue;
		}

	// check for negation

	JParseResult result = JParseAsNegation(expr, length, theVariableList, theDecision);
	if (result == kJParsedOK)
		{
		return kJTrue;
		}
	else if (result == kJParseError)
		{
		return kJFalse;
		}

	// check for "is unknown"

	result = JParseAsUnknown(expr, length, theVariableList, theDecision);
	if (result == kJParsedOK)
		{
		return kJTrue;
		}
	else if (result == kJParseError)
		{
		return kJFalse;
		}

	// check for discrete variable

	result = JParseAsDiscreteComparison(expr, length, theVariableList, theDecision);
	if (result == kJParsedOK)
		{
		return kJTrue;
		}
	else if (result == kJParseError)
		{
		return kJFalse;
		}

	// check for numeric comparison

	if (JContainsComparisonOperator(expr, length, &type, &start, &end))
		{
		JFunction* arg1 = NULL;
		JFunction* arg2 = NULL;

		if (!JRecurseFunction(expr, start, theVariableList, &arg1) ||
			!JRecurseFunction(expr + end, length - end, theVariableList, &arg2))
			{
			delete arg1;
			delete arg2;
			return kJFalse;
			}

		if (type == kJFunctionEqualityType)
			{
			*theDecision = new JFunctionEquality(arg1, arg2);
			}
		else if (type == kJLessThanType)
			{
			*theDecision = new JLessThan(arg1, arg2);
			}
		else if (type == kJLessEqualThanType)
			{
			*theDecision = new JLessEqualThan(arg1, arg2);
			}
		else if (type == kJGreaterThanType)
			{
			*theDecision = new JGreaterThan(arg1, arg2);
			}
		else if (type == kJGreaterEqualThanType)
			{
			*theDecision = new JGreaterEqualThan(arg1, arg2);
			}
		else
			{
			cerr << "JRecurseDecision:  unknown comparison operator" << endl;
			delete arg1;
			delete arg2;
			return kJFalse;
			}
		assert( *theDecision != NULL );
		return kJTrue;
		}

	// this string is not a decision

	JString errorStr(expr, length);
	errorStr.Prepend("\"");
	errorStr += "\" is not a valid boolean expression";
	(JGetUserNotification())->ReportError(errorStr);
	return kJFalse;
}
JParseResult
JParseAsFunctionWithArgs
	(
	const JCharacter*		origExpr,
	const JSize				origLength,
	const JVariableList*	theVariableList,
	JFunction**				theFunction,
	const JBoolean			allowUIF
	)
{
	*theFunction = NULL;

	// remove enclosing parentheses

	const JCharacter* expr = origExpr;
	const JSize length     = JStripParentheses(&expr, origLength);

	// check if expr starts with a function name

	const JSize fnCount            = JPGetStdFunctionCount();
	const JStdFunctionInfo* fnInfo = JPGetStdFunctionInfo();

	JBoolean found = kJFalse;
	JFunctionType type = kJSquareRootType;
	const JCharacter* argsStart = NULL;
	JSize argsLength = 0, argCount = 0, nameLength = 0;
	for (JIndex i=1; i<=fnCount; i++)
		{
		if (JStringBeginsWith(expr, length, fnInfo[i-1].name))
			{
			found    = kJTrue;
			type     = fnInfo[i-1].type;
			argCount = fnInfo[i-1].argCount;

			nameLength = strlen(fnInfo[i-1].name);
			argsStart  = expr + nameLength;
			argsLength = length - nameLength - 1;

			break;
			}
		}
	if (!found)
		{
		return kJNotMyProblem;
		}

	// check if the argument block is correctly closed

	if (!((*(expr + nameLength-1) == '(' && *(expr + length-1) == ')') ||
		  (*(expr + nameLength-1) == '[' && *(expr + length-1) == ']')) )
		{
		return kJNotMyProblem;
		}

	// create the appropriate object

	JFunctionWithArgs* stdFunction = NULL;
	if (type == kJSquareRootType)
		{
		stdFunction = new JSquareRoot();
		}
	else if (type == kJAbsValueType)
		{
		stdFunction = new JAbsValue();
		}
	else if (type == kJSignType)
		{
		stdFunction = new JAlgSign();
		}
	else if (type == kJRoundType)
		{
		stdFunction = new JRoundToInt();
		}
	else if (type == kJTruncateType)
		{
		stdFunction = new JTruncateToInt();
		}

	else if (type == kJLog10Type)
		{
		stdFunction = new JLogB();	// will set base later
		}
	else if (type == kJLogEType)
		{
		stdFunction = new JLogE();
		}
	else if (type == kJLog2Type)
		{
		stdFunction = new JLogB();	// will set base later
		}

	else if (type == kJSineType)
		{
		stdFunction = new JSine();
		}
	else if (type == kJCosineType)
		{
		stdFunction = new JCosine();
		}
	else if (type == kJTangentType)
		{
		stdFunction = new JTangent();
		}
	else if (type == kJArcSineType)
		{
		stdFunction = new JArcSine();
		}
	else if (type == kJArcCosineType)
		{
		stdFunction = new JArcCosine();
		}
	else if (type == kJArcTangentType)
		{
		stdFunction = new JArcTangent();
		}

	else if (type == kJHypSineType)
		{
		stdFunction = new JHypSine();
		}
	else if (type == kJHypCosineType)
		{
		stdFunction = new JHypCosine();
		}
	else if (type == kJHypTangentType)
		{
		stdFunction = new JHypTangent();
		}
	else if (type == kJArcHypSineType)
		{
		stdFunction = new JArcHypSine();
		}
	else if (type == kJArcHypCosineType)
		{
		stdFunction = new JArcHypCosine();
		}
	else if (type == kJArcHypTangentType)
		{
		stdFunction = new JArcHypTangent();
		}

	else if (type == kJRealPartType)
		{
		stdFunction = new JRealPart();
		}
	else if (type == kJImagPartType)
		{
		stdFunction = new JImagPart();
		}
	else if (type == kJPhaseAngleType)
		{
		stdFunction = new JPhaseAngle();
		}
	else if (type == kJConjugateType)
		{
		stdFunction = new JConjugate();
		}

	else if (type == kJLogBType)
		{
		stdFunction = new JLogB();
		}
	else if (type == kJArcTangent2Type)
		{
		stdFunction = new JArcTangent2();
		}
	else if (type == kJRotateType)
		{
		stdFunction = new JRotateComplex();
		}

	else if (type == kJMaxFuncType)
		{
		stdFunction = new JMaxFunc();
		}
	else if (type == kJMinFuncType)
		{
		stdFunction = new JMinFunc();
		}
	else if (type == kJParallelType)
		{
		stdFunction = new JParallel();
		}
	else
		{
		cerr << "JParseAsFunctionWithArgs:  unknown function type" << endl;
		return kJParseError;
		}
	assert( stdFunction != NULL );

	// parse each argument

	const JCharacter* argSeparatorStr = JPGetArgSeparatorString();
	const JSize argSeparatorLength    = JPGetArgSeparatorStringLength();

	if (argCount == 1)
		{
		// parse the entire string as the single argument

		JFunction* arg = NULL;
		const JBoolean ok =
			JRecurseFunction(argsStart, argsLength, theVariableList, &arg, allowUIF);
		if (ok && (type == kJLog10Type || type == kJLog2Type))
			{
			JConstantValue* base = NULL;
			if (type == kJLog10Type)
				{
				base = new JConstantValue(10.0);
				}
			else if (type == kJLog2Type)
				{
				base = new JConstantValue(2.0);
				}
			assert( base != NULL );
			stdFunction->SetArg(1, base);
			stdFunction->SetArg(2, arg);
			*theFunction = stdFunction;
			return kJParsedOK;
			}
		else if (ok)
			{
			stdFunction->SetArg(1, arg);
			*theFunction = stdFunction;
			return kJParsedOK;
			}
		else
			{
			delete stdFunction;
			return kJParseError;
			}
		}
	else if (argCount != kJUnlimitedArgs)
		{
		// parse all but the last argument by searching forward
		// for commas with JFindFirstOperator

		const JCharacter* argStart = argsStart;
		JSize remainderLength = argsLength;
		for (JIndex i=1; i<argCount; i++)
			{
			JSize offset;
			if (!JFindFirstOperator(argStart, remainderLength, argSeparatorStr, &offset))
				{
				JString errorStr(expr, length);
				errorStr.Prepend("\"");
				errorStr += "\" has too few arguments";
				(JGetUserNotification())->ReportError(errorStr);
				delete stdFunction;
				return kJParseError;
				}
			JFunction* arg = NULL;
			if (!JRecurseFunction(argStart, offset, theVariableList, &arg, allowUIF))
				{
				delete stdFunction;
				return kJParseError;
				}
			stdFunction->SetArg(i, arg);
			argStart += offset + argSeparatorLength;
			remainderLength -= offset + argSeparatorLength;
			}

		// make sure that there is only one argument left

		JSize offset;
		if (JFindFirstOperator(argStart, remainderLength, argSeparatorStr, &offset))
			{
			JString errorStr(expr, length);
			errorStr.Prepend("\"");
			errorStr += "\" has too many arguments";
			(JGetUserNotification())->ReportError(errorStr);
			delete stdFunction;
			return kJParseError;
			}

		// parse the last argument in the list

		JFunction* arg = NULL;
		if (!JRecurseFunction(argStart, remainderLength, theVariableList, &arg, allowUIF))
			{
			delete stdFunction;
			return kJParseError;
			}
		stdFunction->SetArg(argCount, arg);
		*theFunction = stdFunction;
		return kJParsedOK;
		}
	else	// argCount == kJUnlimitedArgs
		{
		// parse all the arguments by searching forward
		// for commas with JFindFirstOperator

		JIndex i=1;
		const JCharacter* argStart = argsStart;
		JSize remainderLength = argsLength;
		JBoolean foundArgSeparator = kJTrue;
		while (foundArgSeparator)
			{
			JSize offset;
			foundArgSeparator =
				JFindFirstOperator(argStart, remainderLength, argSeparatorStr, &offset);
			if (!foundArgSeparator)
				{
				offset = remainderLength;
				}
			JFunction* arg = NULL;
			if (!JRecurseFunction(argStart, offset, theVariableList, &arg, allowUIF))
				{
				delete stdFunction;
				return kJParseError;
				}
			stdFunction->SetArg(i, arg);
			i++;
			argStart += offset + argSeparatorLength;
			remainderLength -= offset + argSeparatorLength;
			}

		*theFunction = stdFunction;
		return kJParsedOK;
		}
}
JBoolean
JRecurseFunction
	(
	const JCharacter*		origExpr,
	const JSize				origLength,
	const JVariableList*	theVariableList,
	JFunction**				theFunction,
	const JBoolean			allowUIF
	)
{
	*theFunction = NULL;

	// remove enclosing parentheses

	const JCharacter* expr = origExpr;
	const JSize length     = JStripParentheses(&expr, origLength);

	if (length == 0)
		{
		(JGetUserNotification())->ReportError("You specified an empty function");
		return kJFalse;
		}

	// check for summation (+,-)

	JParseResult result = JParseAsSummation(expr, length, theVariableList,
											theFunction, allowUIF);
	if (result == kJParsedOK)
		{
		return kJTrue;
		}
	else if (result == kJParseError)
		{
		return kJFalse;
		}

	// check for product before division
	// so we correctly parse x/y*z as (x/y)*z

	result = JParseAsProduct(expr, length, theVariableList, theFunction, allowUIF);
	if (result == kJParsedOK)
		{
		return kJTrue;
		}
	else if (result == kJParseError)
		{
		return kJFalse;
		}

	// check for division

	result = JParseAsDivision(expr, length, theVariableList, theFunction, allowUIF);
	if (result == kJParsedOK)
		{
		return kJTrue;
		}
	else if (result == kJParseError)
		{
		return kJFalse;
		}

	// check for exponentiation

	result = JParseAsExponentiation(expr, length, theVariableList, theFunction, allowUIF);
	if (result == kJParsedOK)
		{
		return kJTrue;
		}
	else if (result == kJParseError)
		{
		return kJFalse;
		}

	// check for standard function

	result = JParseAsFunctionWithArgs(expr, length, theVariableList, theFunction, allowUIF);
	if (result == kJParsedOK)
		{
		return kJTrue;
		}
	else if (result == kJParseError)
		{
		return kJFalse;
		}

	// check for function of discrete variable

	result = JParseAsFunctionOfDiscrete(expr, length, theVariableList, theFunction, allowUIF);
	if (result == kJParsedOK)
		{
		return kJTrue;
		}
	else if (result == kJParseError)
		{
		return kJFalse;
		}

	// check for named constant

	if (JIsNamedConstant(expr, length, theFunction))
		{
		return kJTrue;
		}

	// check for variable name

	result = JParseAsNumericVariable(expr, length, theVariableList, theFunction, allowUIF);
	if (result == kJParsedOK)
		{
		return kJTrue;
		}
	else if (result == kJParseError)
		{
		return kJFalse;
		}

	// check for empty JUserInputFunction

	if (allowUIF && JStringsEqual(expr, length, JUserInputFunction::GetEmptyString()))
		{
		*theFunction = new JUserInputFunction(theVariableList,
											  JGetCurrFontManager(),
											  JGetCurrColormap());
		assert( *theFunction != NULL );
		return kJTrue;
		}

	// check for constant, must occupy entire string

	JString valueStr(expr, length);
	JBoolean isPercentage = kJFalse;
	if (valueStr.GetLastCharacter() == '%')
		{
		isPercentage = kJTrue;
		valueStr.RemoveSubstring(valueStr.GetLength(), valueStr.GetLength());
		valueStr.TrimWhitespace();
		}

	JFloat value;
	if (valueStr.ConvertToFloat(&value))
		{
		if (isPercentage)
			{
			value /= 100.0;
			}

		*theFunction = new JConstantValue(value);
		assert( *theFunction != NULL );
		return kJTrue;
		}
	else if (jerrno() == ERANGE)
		{
		JString errorStr(expr, length);
		errorStr.Prepend("\"");
		errorStr += "\" is too large to be represented.";
		(JGetUserNotification())->ReportError(errorStr);
		return kJFalse;
		}

	// this string is not a function

	JString errorStr(expr, length);
	errorStr.Prepend("\"");
	errorStr += "\" is not a valid function.";
	(JGetUserNotification())->ReportError(errorStr);
	return kJFalse;
}
JParseResult
JParseVariable
	(
	const JCharacter*		origExpr,
	const JSize				origLength,
	const JVariableList*	theVariableList,
	JIndex*					varIndex,
	JFunction**				arrayIndex,
	const JBoolean			allowUIF
	)
{
	*arrayIndex = NULL;

	// remove enclosing parentheses

	const JCharacter* expr = origExpr;
	JSize length           = JStripParentheses(&expr, origLength);

	// strip off array index first

	JSize offset;
	if (JStringContains(expr, length, "[", &offset) &&
		JStringEndsWith(expr, length, "]"))
		{
		const JCharacter* indexExpr = expr + offset + 1;	// move past [
		JSize indexLength = length - offset - 2;			// ignore trailing ]
		if (!JRecurseFunction(indexExpr, indexLength, theVariableList, arrayIndex, allowUIF))
			{
			return kJParseError;
			}
		length = offset;
		}

	// look for variable name

	if (theVariableList->ParseVariableName(expr, length, varIndex))
		{
		const JBoolean isArray = theVariableList->IsArray(*varIndex);
		if (*arrayIndex == NULL && isArray)
			{
			JString errorStr(expr, length);
			errorStr.Prepend("\"");
			errorStr += "\" is an array";
			(JGetUserNotification())->ReportError(errorStr);
			return kJParseError;
			}
		if (*arrayIndex != NULL && !isArray)
			{
			delete *arrayIndex;
			*arrayIndex = NULL;

			JString errorStr(expr, length);
			errorStr.Prepend("\"");
			errorStr += "\" is not an array";
			(JGetUserNotification())->ReportError(errorStr);
			return kJParseError;
			}
		return kJParsedOK;
		}
	else if (*arrayIndex != NULL)
		{
		delete *arrayIndex;
		*arrayIndex = NULL;

		JString errorStr(expr, length);
		errorStr.Prepend("\"");
		errorStr += "\" is not a variable";
		(JGetUserNotification())->ReportError(errorStr);
		return kJParseError;
		}
	else
		{
		return kJNotMyProblem;
		}
}
JParseResult
JParseAsFunctionOfDiscrete
	(
	const JCharacter*		origExpr,
	const JSize				origLength,
	const JVariableList*	theVariableList,
	JFunction**				theFunction,
	const JBoolean			allowUIF
	)
{
	*theFunction = NULL;

	// remove enclosing parentheses

	const JCharacter* expr = origExpr;
	const JSize length     = JStripParentheses(&expr, origLength);

	// check if expr starts with a function name

	const JSize fnCount                   = JPGetFnOfDiscreteCount();
	const JFunctionOfDiscreteInfo* fnInfo = JPGetFnOfDiscreteInfo();

	JBoolean found = kJFalse;
	JFunctionType type = kJSquareRootType;
	const JCharacter* argStart = NULL;
	JSize argLength = 0, nameLength = 0;
	for (JSize i=1; i<=fnCount; i++)
		{
		if (JStringBeginsWith(expr, length, fnInfo[i-1].name))
			{
			found = kJTrue;
			type  = fnInfo[i-1].type;

			nameLength = strlen(fnInfo[i-1].name);
			argStart  = expr + nameLength;
			argLength = length - nameLength - 1;
			}
		}
	if (!found)
		{
		return kJNotMyProblem;
		}

	// check if the argument block is correctly closed

	if (!((*(expr + nameLength-1) == '(' && *(expr + length-1) == ')') ||
		  (*(expr + nameLength-1) == '[' && *(expr + length-1) == ']')) )
		{
		return kJNotMyProblem;
		}

	// parse the argument as a discrete variable name

	JIndex varIndex;
	JFunction* arrayIndex = NULL;

	const JParseResult result = JParseVariable(argStart, argLength, theVariableList,
											   &varIndex, &arrayIndex, allowUIF);
	if (result != kJParsedOK || !theVariableList->IsDiscrete(varIndex))
		{
		delete arrayIndex;

		JString errorStr(argStart, argLength);
		errorStr.Prepend("\"");
		errorStr += "\" is not a discrete variable";
		(JGetUserNotification())->ReportError(errorStr);
		return kJParseError;
		}

	// create the appropriate object

	if (type == kJDiscVarValueIndexType)
		{
		*theFunction = new JDiscVarValueIndex(theVariableList, varIndex, arrayIndex);
		}
	else if (type == kJDiscVarValueType)
		{
		*theFunction = new JDiscVarValue(theVariableList, varIndex, arrayIndex);
		}
	else
		{
		cerr << "JParseAsFunctionOfDiscrete:  unknown function type" << endl;
		delete arrayIndex;
		return kJParseError;
		}
	assert( *theFunction != NULL );

	return kJParsedOK;
}
JParseResult
JParseAsDiscreteComparison
	(
	const JCharacter*		origExpr,
	const JSize				origLength,
	const JVariableList*	theVariableList,
	JDecision**				theDecision
	)
{
	*theDecision = NULL;

	// remove enclosing parentheses

	const JCharacter* expr = origExpr;
	const JSize length     = JStripParentheses(&expr, origLength);

	// search for equal sign

	JSize offset;
	if (!JStringContains(expr, length, JPGetEqualityString(), &offset))
		{
		return kJNotMyProblem;
		}

	// check front part for a single variable name
	// if it doesn't work, we assume it's a function

	JIndex varIndex;
	JFunction* arrayIndex = NULL;

	const JParseResult result = JParseVariable(expr, offset, theVariableList,
											   &varIndex, &arrayIndex);
	if (result != kJParsedOK)
		{
		return result;
		}

	// check last part for a legal variable value

	const JSize valueOffset      = offset + JPGetEqualityStringLength();
	const JCharacter* valueStart = expr + valueOffset;
	const JSize valueLength      = JStripParentheses(&valueStart, length - valueOffset);

	JIndex value;
	if (theVariableList->IsNumeric(varIndex))
		{
		// check for comparison with appropriate equivalent of "unknown"

		const JString& unknownName = theVariableList->GetUnknownValueSymbol(varIndex);
		if (JStringsEqual(valueStart, valueLength, unknownName))
			{
			// return JValueUnknown object

			*theDecision = new JValueUnknown(theVariableList, varIndex, arrayIndex);
			assert( *theDecision != NULL );
			return kJParsedOK;
			}
		else
			{
			delete arrayIndex;
			return kJNotMyProblem;
			}
		}
	else if (theVariableList->ParseDiscreteValue(valueStart, valueLength, varIndex, &value))
		{
		// return JDiscreteEquality object

		*theDecision = new JDiscreteEquality(theVariableList, varIndex, arrayIndex, value);
		assert( *theDecision != NULL );
		return kJParsedOK;
		}

	// check for another discrete variable

	JIndex varIndex2;
	JFunction* arrayIndex2 = NULL;

	const JParseResult result2 = JParseVariable(valueStart, valueLength, theVariableList,
											    &varIndex2, &arrayIndex2);
	if (result2 == kJParsedOK && theVariableList->IsDiscrete(varIndex2) &&
		theVariableList->HaveSameValues(varIndex, varIndex2))
		{
		// return JDiscreteVarEquality object

		*theDecision = new JDiscreteVarEquality(theVariableList, varIndex, arrayIndex,
												varIndex2, arrayIndex2);
		assert( *theDecision != NULL );
		return kJParsedOK;
		}

	delete arrayIndex;
	delete arrayIndex2;

	if (result2 == kJParsedOK)
		{
		// it parsed, but the variables can't be compared

		JString errorStr = theVariableList->GetVariableName(varIndex);
		errorStr += " cannot be compared with ";
		errorStr += JString(valueStart, valueLength);
		(JGetUserNotification())->ReportError(errorStr);
		return kJParseError;
		}
	else if (result2 == kJParseError)
		{
		return kJParseError;
		}
	else
		{
		// we couldn't make sense of the second half, so it's an error

		JString errorStr(valueStart, valueLength);
		errorStr.Prepend("\"");
		errorStr += "\" is not a possible value of ";
		errorStr += theVariableList->GetVariableName(varIndex);
		(JGetUserNotification())->ReportError(errorStr);
		return kJParseError;
		}
}