SETTINGS_READER_RESULT Settings_parseDataChannelSetting(char const * const setting, int lineNo)
{
    char * pSettingString;
    char * pValueString;
    char * pChannelString;
    char * pChannelSettingString;

    uint8_t length = strlen(setting);

    char lowercaseCopy[MAX_LINE_LENGTH];

    strncpy_safe(lowercaseCopy, setting, length+1);
    toLowerStr(lowercaseCopy);

    bool success = true;

    if (*setting == '#') { return noError(); } // Line is a comment
    
    // If line is blank, fail early
    if (stringIsWhitespace(setting)) { return noError(); }

    // Split the string by '=' to get setting and name
    success &= splitAndStripWhiteSpace(lowercaseCopy, '=', &pSettingString, NULL, &pValueString, NULL);
    if (!success) { return noEqualsError(lineNo); }

    // Split the setting to get channel and setting name
    success &= splitAndStripWhiteSpace(pSettingString, '.', &pChannelString, NULL, &pChannelSettingString, NULL);
    if (!success) { return noSettingError(lineNo); }

    int8_t ch = Settings_getChannelFromSetting(pChannelString);
    if (ch == -1) { return noChannelError(lineNo); }

    if (0 == strncmp(pChannelSettingString, "type", 4))
    {
        // Try to interpret setting as a channel type
        s_fieldTypes[ch] = Setting_parseSettingAsType(pValueString);
        if (s_fieldTypes[ch] == INVALID_TYPE) { return unknownTypeError(lineNo, pValueString); }

        setupChannel(ch, s_fieldTypes[ch]);
        return noError();
    }

    /* If processing got this far, the setting needs to be interpreted based on the channel datatype */
    switch (s_fieldTypes[ch])
    {
    case VOLTAGE:
        return tryParseAsVoltageSetting(ch, pChannelSettingString, pValueString, lineNo);
    case CURRENT:
        return tryParseAsCurrentSetting(ch, pChannelSettingString, pValueString, lineNo);
    case TEMPERATURE_C:
    case TEMPERATURE_F:
    case TEMPERATURE_K:
        return tryParseAsThermistorSetting(ch, pChannelSettingString, pValueString, lineNo);

    case INVALID_TYPE:
    default:
        // If the channel type is not set prior to any other settings, this is an error.
        return channelNotSetError(lineNo, ch);
    }
}
static SETTINGS_READER_RESULT tryParseAsCurrentSetting(uint8_t ch, char * pSettingName, char * pValueString, int lineNo)
{
    float setting;
    
    bool settingParsedAsFloat = Setting_parseSettingAsFloat(&setting, pValueString);
    
    if (0 == strncmp(pSettingName, "mvperbit", 8))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((CURRENTCHANNEL*)s_channels[ch])->mvPerBit = setting;
        s_valuesSetBitFields[ch] |= 0x01;
        return noError();
    }
    
    if (0 == strncmp(pSettingName, "offset", 6))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((CURRENTCHANNEL*)s_channels[ch])->offset = setting;
        s_valuesSetBitFields[ch] |= 0x02;
        return noError();
    }

    if (0 == strncmp(pSettingName, "mvperamp", 8))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((CURRENTCHANNEL*)s_channels[ch])->mvPerAmp = setting;
        s_valuesSetBitFields[ch] |= 0x04;
        return noError();
    }

    return unknownSettingError(lineNo, pSettingName);
}
static SETTINGS_READER_RESULT tryParseAsVoltageSetting(uint8_t ch, char * pSettingName, char * pValueString, int lineNo)
{
    float setting;

    bool settingParsedAsFloat = Setting_parseSettingAsFloat(&setting, pValueString);

    if (0 == strncmp(pSettingName, "mvperbit", 8))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((VOLTAGECHANNEL*)s_channels[ch])->mvPerBit = setting;
        s_valuesSetBitFields[ch] |= 0x01;
        return noError();
    }

    if (0 == strncmp(pSettingName, "r1", 2))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((VOLTAGECHANNEL*)s_channels[ch])->R1 = setting;
        s_valuesSetBitFields[ch] |= 0x02;
        return noError();
    }

    if (0 == strncmp(pSettingName, "r2", 2))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((VOLTAGECHANNEL*)s_channels[ch])->R2 = setting;
        s_valuesSetBitFields[ch] |= 0x04;
        return noError();
    }

    if (0 == strncmp(pSettingName, "offset", 6))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((VOLTAGECHANNEL*)s_channels[ch])->offset = setting;
        s_valuesSetBitFields[ch] |= 0x08;
        return noError();
    }

    if (0 == strncmp(pSettingName, "multiplier", 10))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((VOLTAGECHANNEL*)s_channels[ch])->multiplier = setting;
        s_valuesSetBitFields[ch] |= 0x10;
        return noError();
    }

    return unknownSettingError(lineNo, pSettingName);
}
static SETTINGS_READER_RESULT tryParseAsThermistorSetting(uint8_t ch, char * pSettingName, char * pValueString, int lineNo)
{
    float setting;
    
    bool settingParsedAsFloat = Setting_parseSettingAsFloat(&setting, pValueString);
    
    if (0 == strncmp(pSettingName, "maxadc", 6))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((THERMISTORCHANNEL*)s_channels[ch])->maxADC = setting;
        s_valuesSetBitFields[ch] |= 0x01;
        return noError();
    }
    
    if (0 == strncmp(pSettingName, "b", 1))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((THERMISTORCHANNEL*)s_channels[ch])->B = setting;
        s_valuesSetBitFields[ch] |= 0x02;
        return noError();
    }

    if (0 == strncmp(pSettingName, "r25", 3))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((THERMISTORCHANNEL*)s_channels[ch])->R25 = setting;
        s_valuesSetBitFields[ch] |= 0x04;
        return noError();
    }

    if (0 == strncmp(pSettingName, "otherr", 6))
    {
        if (!settingParsedAsFloat) { return invalidSettingError(lineNo, pSettingName); }
        ((THERMISTORCHANNEL*)s_channels[ch])->otherR = setting;
        s_valuesSetBitFields[ch] |= 0x08;
        return noError();
    }

    if (0 == strncmp(pSettingName, "highside", 8))
    {
        ((THERMISTORCHANNEL*)s_channels[ch])->highside = (*pValueString != '0');
        s_valuesSetBitFields[ch] |= 0x10;
        return noError();
    }

    return unknownSettingError(lineNo, pSettingName);
}
void FileSystemDevice::FileState::complete_close(PacketHeader *packet_)
 {
  Packet<uint8,Sys::AsyncFile::CloseExt,CloseExt> packet=packet_;

  auto ext=packet.getExt();
  auto ext2=packet.getDeepExt<1>();

  if( ext->isOk() )
    {
     ext2->noError();
    }
  else
    {
     ext2->setError(MakeError(ext,FileError_CloseFault));
    }

  packet.popExt().complete();
 }
void DetailExcelWidget::BatchCheck(QVector<int> vec)
{
    BatchTotal = vec.size();
    curCount = 0;
    isBatch = true;
    deleteBatchVec();
    auto sourceListWidget = dynamic_cast<SourceListWidget*>(g_listWidget);
    for(int i=0; i<vec.size(); i++){
        int index = vec.at(i);
        auto item = sourceListWidget->item(index);
        QString name = item->data(Qt::UserRole).toString();
        BatchFilterThread* t = new BatchFilterThread();
        connect(t, SIGNAL(hasErrorSignal(QString)), this, SLOT(findError(QString)));
        connect(t, SIGNAL(noErrorSignal(QString)), this, SLOT(noError(QString)));
        t->setFile(name);
        filterVec.push_back(t);
    }
    filterVec.at(0)->start();
}
void DetailExcelWidget::checkError()
{
    isBatch = false;
    BatchFilterThread* t = new BatchFilterThread();
    QObject::connect(t, SIGNAL(hasErrorSignal(QString)), this, SLOT(findError(QString)));
    QObject::connect(t, SIGNAL(noErrorSignal(QString)), this, SLOT(noError(QString)));
    filterVec.push_back(t);
    t->setFile(file_name);
    t->changeToFilterType(typeVec);
    QVector<QStringList> vec__;
    for(int i=0; i<m_vec.size(); i++){
        auto vecChild = m_vec.at(i);
        QStringList listChild;
        for(int n=0; n<vecChild->size(); n++){
            auto item = vecChild->at(n);
            listChild.push_back(item->Checkbox->text());
        }
        vec__.push_back(listChild);
    }
    t->addNameVec(vec__);
    t->start();
}