string Decode::Read(string input) { preBuffer+=input; string s; size_t i; char c; for(i=0;i<preBuffer.size();++i) { c = preBuffer[i]; switch(state) //what state are we in { case WHITE: //reading whitespace if (isspace(c) ) break; //keep reading if( isdigit(c) ) //digit, switch states { buffer+=c; state=DIGIT; } else //non-white, non-digit { string s="Parse Error: Bad input, expected digit"; throw ParsingError(s.c_str()); } break; case DIGIT: if(isdigit(c)) //keep adding to buffer { buffer+=c; break; } if(c==':') //end of buffer size { state=COUNT; //change to count state count=atoi( buffer.c_str() ); //build _count buffer.erase();//empty the internal buffer } else //found a non-digit, non-colon { string s="Parse Error: Bad input, expected digit or colon"; throw ParsingError(s.c_str()); } break; case COUNT://reading count number of bytes buffer+=c; count--; if(count==0) //done reading, return the string { state=WHITE;//reset the state s=buffer; buffer.erase(); } break; } if(s.size()>0) break; } preBuffer.erase(0,i+1); return s; }
void Parsing::getCommands(std::istream &in, Core *core) { std::string line; if (in) { while (getline(in, line)) { if (in == std::cin and line.find(";;") != line.npos) { break; } if (line.size() != 0 and line.at(0) != ';') { if (line.find_first_of(';') != line.npos) { line.erase(line.find_first_of(';'), line.npos); } if (line == "exit") { this->_exit = true; } try { this->commandLine(line, core); } catch (const ParsingError &error) { throw ParsingError(this->getErrorLine(error.what())); } } this->_line++; } if (this->_exit == false) { throw ParsingError("You must finish your commands file with exit instruction"); } } else { throw ParsingError("Commands file does not exists"); } }
void Parsing::checkElements(const std::string &instr) { if (instr == "pop" and this->_elements == 0) { throw ParsingError("Pop instruction on an empty list"); } else if ((instr == "add" or instr == "sub" or instr == "mul" or instr == "div" or instr == "mod") and this->_elements < 2) { throw ParsingError("Calculate instruction on a list without more 2 elements"); } else if ((instr == "add" or instr == "sub" or instr == "mul" or instr == "div" or instr == "mod" or instr == "pop")) { this->_elements--; } else if (instr == "push") { this->_elements++; } }
void Parsing::commandLine(const std::string &line, Core *core) { std::istringstream word(line); std::string instruction; std::string type; std::string value; bool status = false; word >> instruction; word >> type; if (!type.empty()) { if (type.find('(') != type.npos and type.find(')') != type.npos) { value = type.substr(type.find_first_of('(') + 1); value = value.substr(0, value.find_last_of(')')); type.erase(type.find_first_of('('), type.npos); status = true; } else { throw ParsingError("A value between () was expected"); } } if (std::find(this->_instructions.begin(), this->_instructions.end(), std::make_pair(instruction, status)) == this->_instructions.end()) { throw ParsingError("Undefined instruction"); } else { if (!type.empty() and this->_values.find(type) == this->_values.end()) { throw ParsingError("Undefined type"); } else { try { this->checkElements(instruction); } catch (const ParsingError &error) { throw ParsingError(error.what()); } try { this->isNumber(value); } catch (const ParsingError &error) { throw ParsingError(error.what()); } this->createInstruction(instruction, type, value, core); } } }
void Parsing::isNumber(const std::string &value) { std::string::const_iterator it = value.begin(); while (it != value.end()) { if (!std::isdigit(*it) and *it != '.' and *it != '-') { throw ParsingError("Value is not a number"); } else { *it++; } } }
void Parsing::createInstruction(const std::string &instr, const std::string &type, const std::string &value, Core *core) { Hatchery hatchery; if (this->_map.find(instr) != this->_map.end()) { try { IOperand *operand = hatchery.createOperand(this->_values[type], value); core->pushMemoryInstruction(this->_map[instr], operand); } catch (const std::exception &error) { throw ParsingError(error.what()); } } }
Form Parser::parse() const { Form ast; auto it = tokens.cbegin(); while (it != tokens.cend()) { if (*it != "(") { std::ostringstream ss; ss << "Error: token " << *it << "is not in an expression"; throw ParsingError(ss.str()); } ast.push_back(parse_expr(++it, tokens.cend())); } return ast; }
void SubsonicLibraryScanner::OnGetAlbumFinished(QNetworkReply* reply) { reply->deleteLater(); pending_requests_.remove(reply); QXmlStreamReader reader(reply); reader.readNextStartElement(); if (reader.name() != "subsonic-response") { ParsingError("Not a subsonic-response. Aborting scan."); return; } if (reader.attributes().value("status") != "ok") { // TODO(Alan Briolat): error handling return; } // Read album information reader.readNextStartElement(); if (reader.name() != "album") { ParsingError("album tag expected. Aborting scan."); return; } QString album_artist = reader.attributes().value("artist").toString(); // Read song information while (reader.readNextStartElement()) { if (reader.name() != "song") { ParsingError("song tag expected. Aborting scan."); return; } Song song; QString id = reader.attributes().value("id").toString(); song.set_title(reader.attributes().value("title").toString()); song.set_album(reader.attributes().value("album").toString()); song.set_track(reader.attributes().value("track").toString().toInt()); song.set_disc(reader.attributes().value("discNumber").toString().toInt()); song.set_artist(reader.attributes().value("artist").toString()); song.set_albumartist(album_artist); song.set_bitrate(reader.attributes().value("bitRate").toString().toInt()); song.set_year(reader.attributes().value("year").toString().toInt()); song.set_genre(reader.attributes().value("genre").toString()); qint64 length = reader.attributes().value("duration").toString().toInt(); length *= kNsecPerSec; song.set_length_nanosec(length); QUrl url = QUrl(QString("subsonic://%1").arg(id)); song.set_url(url); song.set_filesize(reader.attributes().value("size").toString().toInt()); // We need to set these to satisfy the database constraints song.set_directory_id(0); song.set_mtime(0); song.set_ctime(0); songs_ << song; reader.skipCurrentElement(); } // Start the next request if albums remain if (!album_queue_.empty()) { GetAlbum(album_queue_.dequeue()); } // If this was the last response, we're done! if (album_queue_.empty() && pending_requests_.empty()) { scanning_ = false; emit ScanFinished(); } }
void SubsonicLibraryScanner::OnGetAlbumListFinished(QNetworkReply* reply, int offset) { reply->deleteLater(); bool skip_read_albums = false; QXmlStreamReader reader(reply); reader.readNextStartElement(); if (reader.name() != "subsonic-response") { ParsingError("Not a subsonic-response. Aborting scan."); return; } if (reader.attributes().value("status") != "ok") { reader.readNextStartElement(); int error = reader.attributes().value("code").toString().toInt(); // Compatibility with Ampache : // When there is no data, Ampache returns NotFound // whereas Subsonic returns empty albumList2 tag switch (error) { case SubsonicService::ApiError_NotFound: skip_read_albums = true; break; default: ParsingError("Response status not ok. Aborting scan."); return; } } int albums_added = 0; if (!skip_read_albums) { reader.readNextStartElement(); if (reader.name() != "albumList2") { ParsingError("albumList2 tag expected. Aborting scan."); return; } while (reader.readNextStartElement()) { if (reader.name() != "album") { ParsingError("album tag expected. Aborting scan."); return; } album_queue_ << reader.attributes().value("id").toString(); albums_added++; reader.skipCurrentElement(); } } if (albums_added > 0) { // Non-empty reply means potentially more albums to fetch GetAlbumList(offset + kAlbumChunkSize); } else if (album_queue_.size() == 0) { // Empty reply and no albums means an empty Subsonic server scanning_ = false; emit ScanFinished(); } else { // Empty reply but we have some albums, time to start fetching songs // Start up the maximum number of concurrent requests, finished requests get // replaced with new ones for (int i = 0; i < kConcurrentRequests && !album_queue_.empty(); ++i) { GetAlbum(album_queue_.dequeue()); } } }
// Parsing QHash<QString, QVariant> ParserPrivate::parse(QStringList argv) { QHash<QString, QVariant> map; QStringListIterator it(argv); QString programName = it.next(); QString optionPrefix; QString flagPrefix; QListIterator<ParameterDefinition *> positionals(m_positionals); QStringList expecting; getPrefix(optionPrefix, flagPrefix); while (it.hasNext()) { QString arg = it.next(); if (!expecting.isEmpty()) // we were expecting an argument { QString name = expecting.first(); if (map.contains(name)) throw ParsingError( QString("Option %2%1 was given multiple times").arg(name, optionPrefix)); map[name] = QVariant(arg); expecting.removeFirst(); continue; } if (arg.startsWith(optionPrefix)) // we have an option { // qDebug("Found option %s", qPrintable(arg)); QString name = arg.mid(optionPrefix.length()); QString equals; if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && name.contains("=")) { int i = name.indexOf("="); equals = name.mid(i + 1); name = name.left(i); } if (m_longLookup.contains(name)) { ParameterDefinition *param = m_longLookup[name]; if (map.contains(param->name)) throw ParsingError(QString("Option %2%1 was given multiple times") .arg(param->name, optionPrefix)); if (param->type == DefinitionType::Switch) map[param->name] = !param->defaultValue.toBool(); else // if (param->type == DefinitionType::Option) { if (m_argStyle == ArgumentStyle::Space) expecting.append(param->name); else if (!equals.isNull()) map[param->name] = equals; else if (m_argStyle == ArgumentStyle::SpaceAndEquals) expecting.append(param->name); else throw ParsingError(QString("Option %2%1 reqires an argument.") .arg(name, optionPrefix)); } continue; } // We need to fall through if the prefixes match if (optionPrefix != flagPrefix) throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix)); } if (arg.startsWith(flagPrefix)) // we have (a) flag(s) { // qDebug("Found flags %s", qPrintable(arg)); QString flags = arg.mid(flagPrefix.length()); QString equals; if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && flags.contains("=")) { int i = flags.indexOf("="); equals = flags.mid(i + 1); flags = flags.left(i); } for (int i = 0; i < flags.length(); i++) { QChar flag = flags.at(i); if (!m_flagLookup.contains(flag)) throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix)); ParameterDefinition *param = m_flagLookup[flag]; if (map.contains(param->name)) throw ParsingError(QString("Option %2%1 was given multiple times") .arg(param->name, optionPrefix)); if (param->type == DefinitionType::Switch) map[param->name] = !param->defaultValue.toBool(); else // if (param->type == DefinitionType::Option) { if (m_argStyle == ArgumentStyle::Space) expecting.append(param->name); else if (!equals.isNull()) if (i == flags.length() - 1) map[param->name] = equals; else throw ParsingError(QString("Flag %4%2 of Argument-requiring Option " "%1 not last flag in %4%3") .arg(param->name, flag, flags, flagPrefix)); else if (m_argStyle == ArgumentStyle::SpaceAndEquals) expecting.append(param->name); else throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)") .arg(param->name, flag, flagPrefix)); } } continue; } // must be a positional argument if (!positionals.hasNext()) throw ParsingError(QString("Too many positional arguments: '%1'").arg(arg)); ParameterDefinition *param = positionals.next(); map[param->name] = arg; } // check if we're missing something if (!expecting.isEmpty()) throw ParsingError(QString("Was still expecting arguments for %2%1").arg( expecting.join(QString(", ") + optionPrefix), optionPrefix)); // fill out gaps for (QListIterator<ParameterDefinition *> it(m_definitions); it.hasNext();) { ParameterDefinition *param = it.next(); if (!map.contains(param->name)) { if (isRequired(param)) throw ParsingError( QStringLiteral("Missing mandatory argument '%1'").arg(param->name)); else map[param->name] = param->defaultValue; } } return map; }
// parsing QHash<QString, QVariant> Parser::parse(QStringList argv) { QHash<QString, QVariant> map; QStringListIterator it(argv); QString programName = it.next(); QString optionPrefix; QString flagPrefix; QListIterator<PositionalDef *> positionals(m_positionals); QStringList expecting; getPrefix(optionPrefix, flagPrefix); while (it.hasNext()) { QString arg = it.next(); if (!expecting.isEmpty()) // we were expecting an argument { QString name = expecting.first(); /* if (map.contains(name)) throw ParsingError( QString("Option %2%1 was given multiple times").arg(name, optionPrefix)); */ map[name] = QVariant(arg); expecting.removeFirst(); continue; } if (arg.startsWith(optionPrefix)) // we have an option { // qDebug("Found option %s", qPrintable(arg)); QString name = arg.mid(optionPrefix.length()); QString equals; if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && name.contains("=")) { int i = name.indexOf("="); equals = name.mid(i + 1); name = name.left(i); } if (m_options.contains(name)) { /* if (map.contains(name)) throw ParsingError(QString("Option %2%1 was given multiple times") .arg(name, optionPrefix)); */ OptionDef *option = m_options[name]; if (option->type == otSwitch) map[name] = true; else // if (option->type == otOption) { if (m_argStyle == ArgumentStyle::Space) expecting.append(name); else if (!equals.isNull()) map[name] = equals; else if (m_argStyle == ArgumentStyle::SpaceAndEquals) expecting.append(name); else throw ParsingError(QString("Option %2%1 reqires an argument.") .arg(name, optionPrefix)); } continue; } throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix)); } if (arg.startsWith(flagPrefix)) // we have (a) flag(s) { // qDebug("Found flags %s", qPrintable(arg)); QString flags = arg.mid(flagPrefix.length()); QString equals; if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && flags.contains("=")) { int i = flags.indexOf("="); equals = flags.mid(i + 1); flags = flags.left(i); } for (int i = 0; i < flags.length(); i++) { QChar flag = flags.at(i); if (!m_flags.contains(flag)) throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix)); OptionDef *option = m_flags[flag]; /* if (map.contains(option->name)) throw ParsingError(QString("Option %2%1 was given multiple times") .arg(option->name, optionPrefix)); */ if (option->type == otSwitch) map[option->name] = true; else // if (option->type == otOption) { if (m_argStyle == ArgumentStyle::Space) expecting.append(option->name); else if (!equals.isNull()) if (i == flags.length() - 1) map[option->name] = equals; else throw ParsingError(QString("Flag %4%2 of Argument-requiring Option " "%1 not last flag in %4%3") .arg(option->name, flag, flags, flagPrefix)); else if (m_argStyle == ArgumentStyle::SpaceAndEquals) expecting.append(option->name); else throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)") .arg(option->name, flag, flagPrefix)); } } continue; } // must be a positional argument if (!positionals.hasNext()) throw ParsingError(QString("Don't know what to do with '%1'").arg(arg)); PositionalDef *param = positionals.next(); map[param->name] = arg; } // check if we're missing something if (!expecting.isEmpty()) throw ParsingError(QString("Was still expecting arguments for %2%1").arg( expecting.join(QString(", ") + optionPrefix), optionPrefix)); while (positionals.hasNext()) { PositionalDef *param = positionals.next(); if (param->required) throw ParsingError( QString("Missing required positional argument '%1'").arg(param->name)); else map[param->name] = param->def; } // fill out gaps QListIterator<OptionDef *> iter(m_optionList); while (iter.hasNext()) { OptionDef *option = iter.next(); if (!map.contains(option->name)) map[option->name] = option->def; } return map; }