void AnalyzeTask::parseProperty(const QString &value, const MI_propertyId_t propertyIdx, AudioFileModel &audioFile, QString &coverMimeType)
{
#if MUTILS_DEBUG
	qDebug("Property #%d = \"%s\"", propertyIdx, MUTILS_UTF8(value.left(24)));
#endif
	switch (propertyIdx)
	{
		case propertyId_container:         audioFile.techInfo().setContainerType(value);                                                                  return;
		case propertyId_container_profile: audioFile.techInfo().setContainerProfile(value);                                                               return;
		case propertyId_duration:          SET_OPTIONAL(double, parseFloat(value, _tmp), audioFile.techInfo().setDuration(qRound(_tmp)));                 return;
		case propertyId_title:             audioFile.metaInfo().setTitle(value);                                                                          return;
		case propertyId_artist:            audioFile.metaInfo().setArtist(value);                                                                         return;
		case propertyId_album:             audioFile.metaInfo().setAlbum(value);                                                                          return;
		case propertyId_genre:             audioFile.metaInfo().setGenre(value);                                                                          return;
		case propertyId_released_date:     SET_OPTIONAL(quint32, parseYear(value, _tmp), audioFile.metaInfo().setYear(_tmp));                             return;
		case propertyId_track_position:    SET_OPTIONAL(quint32, parseUnsigned(value, _tmp), audioFile.metaInfo().setPosition(_tmp));                     return;
		case propertyId_comment:           audioFile.metaInfo().setComment(value);                                                                        return;
		case propertyId_format:            audioFile.techInfo().setAudioType(value);                                                                      return;
		case propertyId_format_version:    audioFile.techInfo().setAudioVersion(value);                                                                   return;
		case propertyId_format_profile:    audioFile.techInfo().setAudioProfile(value);                                                                   return;
		case propertyId_channel_s_:        SET_OPTIONAL(quint32, parseUnsigned(value, _tmp), audioFile.techInfo().setAudioChannels(_tmp));                return;
		case propertyId_samplingrate:      SET_OPTIONAL(quint32, parseUnsigned(value, _tmp), audioFile.techInfo().setAudioSamplerate(_tmp));              return;
		case propertyId_bitdepth:          SET_OPTIONAL(quint32, parseUnsigned(value, _tmp), audioFile.techInfo().setAudioBitdepth(_tmp));                return;
		case propertyId_bitrate:           SET_OPTIONAL(quint32, parseUnsigned(value, _tmp), audioFile.techInfo().setAudioBitrate(DIV_RND(_tmp, 1000U))); return;
		case propertyId_bitrate_mode:      SET_OPTIONAL(quint32, parseRCMode(value, _tmp), audioFile.techInfo().setAudioBitrateMode(_tmp));               return;
		case propertyId_encoded_library:   audioFile.techInfo().setAudioEncodeLib(cleanAsciiStr(value));                                                  return;
		case propertyId_cover_mime:        coverMimeType = value;                                                                                         return;
		case propertyId_cover_data:        retrieveCover(audioFile, coverMimeType, value);                                                                return;
		default: MUTILS_THROW_FMT("Invalid property ID: %d", propertyIdx);
	}
}
Beispiel #2
0
unsigned long Properties::getUnsigned(const std::string& key,
				      unsigned long defaultValue,
				      bool terse) const
{
    unsigned long result;
    const_iterator iter = find(key);

    if (iter == end()) {
        if (terse) {
	    Log::log(logID, Log::LOG_MAX_DEBUG,
	         "No value specified for key %s, using default value.", 
			key.c_str());
        }
	result = defaultValue;
    } else {
	try {
	   result = parseUnsigned(key, iter->second);
        } catch (...) {
           if (terse) {
	       Log::log(logID, Log::LOG_MAX_DEBUG,
	         "Invalid value specified for key %s, using default value.", 
	               key.c_str());
           }
           result = defaultValue;
	}
    }
    return result;
}
Beispiel #3
0
// parse minikmer length from string and correct it as necessary
static inline unsigned
getMiniKmerLength(char *h)
{
    unsigned minikmer_length = parseUnsigned(h);

#ifdef PART_MINIKMER_BITS
    unsigned limit = g__FULLKMER_LENGTH * 2;
    if (minikmer_length > limit) {
        fprintf(stderr,"WARNING: mini k-mer bits cannot be larger than double the full k-mer length %u!  Using mini k-mer bits of %u instead.\n",
            g__FULLKMER_LENGTH, limit);
        minikmer_length = limit;
    }
#else
    unsigned limit = g__FULLKMER_LENGTH;
    if (minikmer_length > limit) {
        fprintf(stderr,"WARNING: mini k-mers cannot be larger than the full k-mer length %u!  Using mini k-mer length of %u instead.\n",
            g__FULLKMER_LENGTH, limit);
        minikmer_length = limit;
    }
#endif

#ifdef PART_MIDDLE_MINIKMER
    if (minikmer_length % 2 == 0) {
        fprintf(stderr,"WARNING: mini k-mers can't be of even length, such as %u.  Using mini k-mer length of %u instead.\n",
            minikmer_length, minikmer_length-1);
        -- minikmer_length;
    }
#endif

    return minikmer_length;
}
Beispiel #4
0
// parse partition count from string and correct (round-up) to power-of-4
static inline unsigned
getNumPartitions(char *h)
{
  unsigned numPartitions = parseUnsigned(h);

  // FIXME: is this only for metis?
#ifdef PART_POWEROF4
  if( !is_power_of_4(numPartitions) )
  {
    unsigned tmp = round_up_power_of_2(numPartitions);
    unsigned pow4 = tmp & 0x55555555UL ? tmp : tmp << 1;

    fprintf(stderr,"WARNING: partitions specified %u is not a power of 4.  Using %u instead.\n",
        numPartitions, pow4);
    numPartitions = pow4;
  }
#endif

  unsigned maxPartitions = (1 << (8 * sizeof(color_t))) - 2;

#ifdef PART_POWEROF4
    if (numPartitions > maxPartitions) {
        unsigned tmp = numPartitions >> 2;
        fprintf(stderr,"WARNING: partitions %u is too large.  Using %u instead.\n", numPartitions, tmp);
        numPartitions = tmp;
    }
Beispiel #5
0
/* Throws 
 *      std::invalid_argument if a value for key is not found
 *	std::range_error if value is too small or large.
 *	std::domain_error if valid is invalid otherwise.
 */
unsigned long Properties::getUnsigned(const std::string& key) const
{
    const_iterator iter = find(key);

    if (iter == end()) {
        throw std::invalid_argument(key + " not found");
    }
    return parseUnsigned(key, iter->second);
}
Beispiel #6
0
time_t gbParseChkDate(char* dateStr, boolean* isOk)
/* parse a date, in YYYY-MM-DD format, converting it to a unix time (as
 * returned by time()).  Sets isOk to false if an error */
{
struct tm tm;
time_t numTime;
ZeroVar(&tm);

*isOk = TRUE;

if (!((strlen(dateStr) == 10) && (dateStr[4] == '-') && (dateStr[7] == '-')))
    *isOk = FALSE;
tm.tm_year = parseUnsigned(dateStr, 0, 4, isOk)-1900;  /* since 1900 */
tm.tm_mon = parseUnsigned(dateStr, 5, 2, isOk)-1;      /* since jan */
tm.tm_mday = parseUnsigned(dateStr, 8, 2, isOk);       /* 1-31 */

/* convert */
if ((numTime = mktime(&tm)) == -1)
    *isOk = FALSE;
return numTime;
}
Beispiel #7
0
static time_t gbParseHumanTimeStamp(char *col, boolean *isOkRet)
/* Parse a time stamp, in  "2004-11-01 01:06:18" format, as returned
 * by mysql timestamp columns 4.1 or later. */
{
boolean isOk = TRUE;
struct tm tm;
time_t numTime;
ZeroVar(&tm);

if (strlen(col) != 19)
    isOk = FALSE;
tm.tm_year = parseUnsigned(col, 0, 4, &isOk)-1900;
if (col[4] != '-')
    isOk = FALSE;
tm.tm_mon = parseUnsigned(col, 5, 2, &isOk);
if (col[7] != '-')
    isOk = FALSE;
tm.tm_mday = parseUnsigned(col, 8, 2, &isOk);
if (col[10] != ' ')
    isOk = FALSE;
tm.tm_hour = parseUnsigned(col, 11, 2, &isOk);
if (col[13] != ':')
    isOk = FALSE;
tm.tm_min = parseUnsigned(col, 14, 2, &isOk);
if (col[16] != ':')
    isOk = FALSE;
tm.tm_sec = parseUnsigned(col, 17, 2, &isOk);
/* convert */
if ((numTime = mktime(&tm)) == -1)
    isOk = FALSE;

*isOkRet = isOk;
return numTime;
}
Beispiel #8
0
// parse kmer_length from string and correct to make odd and less than 32 bases long
static inline unsigned
getKmerLength(char *h)
{
  unsigned kmer_length = parseUnsigned(h);

  if (kmer_length > 31) {
    fprintf(stderr,"WARNING: Velour can't handle k-mers as long as %u!  Using k-mer length of 31 instead.\n",
	   kmer_length);
    kmer_length = 31;
  } else if (kmer_length % 2 == 0) {
    fprintf(stderr,"WARNING: Velour can't work with even length k-mers, such as %u.  Using k-mer length of %u instead.\n",
	   kmer_length, kmer_length - 1);
    kmer_length--;
  }
  return kmer_length;
}
bool AnalyzeTask::parseYear(const QString &str, quint32 &value)
{
	if (str.startsWith(QLatin1String("UTC"), Qt::CaseInsensitive))
	{
		const QDate date = QDate::fromString(str.mid(3).trimmed().left(10), QLatin1String("yyyy-MM-dd"));
		if (date.isValid())
		{
			value = date.year();
			return true;
		}
		return false;
	}
	else
	{
		return parseUnsigned(str, value);
	}
}
Beispiel #10
0
static time_t gbParseNumTimeStamp(char *col, boolean *isOkRet)
/* Parse a time stamp, in "YYYYMMDDHHMMSS" format, as returned
 * by mysql timestamp columns before 4.1. */
{
boolean isOk = TRUE;
struct tm tm;
time_t numTime;
ZeroVar(&tm);

if (strlen(col) != 14)
    isOk = FALSE;
tm.tm_year = parseUnsigned(col, 0, 4, &isOk)-1900;
tm.tm_mon = parseUnsigned(col, 4, 2, &isOk);
tm.tm_mday = parseUnsigned(col, 6, 2, &isOk);
tm.tm_hour = parseUnsigned(col, 8, 2, &isOk);
tm.tm_min = parseUnsigned(col, 10, 2, &isOk);
tm.tm_sec = parseUnsigned(col, 12, 2, &isOk);
/* convert */
if ((numTime = mktime(&tm)) == -1)
    isOk = FALSE;

*isOkRet = isOk;
return numTime;
}
bool AnalyzeTask::analyzeAvisynthFile(const QString &filePath, AudioFileModel &info)
{
	QProcess process;
	MUtils::init_process(process, QFileInfo(m_avs2wavBin).absolutePath());

	process.start(m_avs2wavBin, QStringList() << QDir::toNativeSeparators(filePath) << "?");

	if(!process.waitForStarted())
	{
		qWarning("AVS2WAV process failed to create!");
		qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData());
		process.kill();
		process.waitForFinished(-1);
		return false;
	}

	bool bInfoHeaderFound = false;

	while(process.state() != QProcess::NotRunning)
	{
		if(MUTILS_BOOLIFY(m_abortFlag))
		{
			process.kill();
			qWarning("Process was aborted on user request!");
			break;
		}
		
		if(!process.waitForReadyRead())
		{
			if(process.state() == QProcess::Running)
			{
				qWarning("AVS2WAV time out. Killing process and skipping file!");
				process.kill();
				process.waitForFinished(-1);
				return false;
			}
		}

		while(process.canReadLine())
		{
			const QString line = QString::fromUtf8(process.readLine().constData()).simplified();
			if(!line.isEmpty())
			{
				if(bInfoHeaderFound)
				{
					const qint32 index = line.indexOf(':');
					if (index > 0)
					{
						const QString key = line.left(index).trimmed();
						const QString val = line.mid(index + 1).trimmed();
						if (!(key.isEmpty() || val.isEmpty()))
						{
							switch (m_avisynthIdx.value(key.toLower(), MI_propertyId_t(-1)))
							{
								case propertyId_duration:     SET_OPTIONAL(quint32, parseUnsigned(val, _tmp), info.techInfo().setDuration(_tmp));        break;
								case propertyId_samplingrate: SET_OPTIONAL(quint32, parseUnsigned(val, _tmp), info.techInfo().setAudioSamplerate(_tmp)); break;
								case propertyId_channel_s_:   SET_OPTIONAL(quint32, parseUnsigned(val, _tmp), info.techInfo().setAudioChannels(_tmp));   break;
								case propertyId_bitdepth:     SET_OPTIONAL(quint32, parseUnsigned(val, _tmp), info.techInfo().setAudioBitdepth(_tmp));   break;
							}
						}
					}
				}
				else
				{
					if(line.contains("[Audio Info]", Qt::CaseInsensitive))
					{
						info.techInfo().setAudioType("Avisynth");
						info.techInfo().setContainerType("Avisynth");
						bInfoHeaderFound = true;
					}
				}
			}
		}
	}
	
	process.waitForFinished();
	if(process.state() != QProcess::NotRunning)
	{
		process.kill();
		process.waitForFinished(-1);
	}

	//Check exit code
	switch(process.exitCode())
	{
	case 0:
		qDebug("Avisynth script was analyzed successfully.");
		return true;
		break;
	case -5:
		qWarning("It appears that Avisynth is not installed on the system!");
		return false;
		break;
	default:
		qWarning("Failed to open the Avisynth script, bad AVS file?");
		return false;
		break;
	}
}
Beispiel #12
0
std::string PropertyParser::parseTemplateType() {
    std::string Result;
    int ParensLevel = 0;
    bool MoveConstToFront = true;
    bool HasConst = false;
    clang::CXXScopeSpec SS;
    do {
        switch(+CurrentTok.getKind()) {
        case clang::tok::eof:
            return {};
        case clang::tok::greatergreater:
            if (ParensLevel > 0)
                break;
            CurrentTok.setKind(clang::tok::greater);
            PrevToken.setKind(clang::tok::greater);
            if (Result[Result.size()-1] == '>')
                Result += " ";
            Result += ">";
            return Result;
        case clang::tok::greater:
            if (ParensLevel > 0)
                break;
            if (Result[Result.size()-1] == '>')
                Result += " ";
            Result += ">";
            Consume();
            return Result;
        case clang::tok::less:
            if (ParensLevel > 0 )
                break;
            Result += "<";
            Consume();
            Result += parseTemplateType();
            if (!PrevToken.is(clang::tok::greater))
                return {};
            MoveConstToFront = false;
            continue;
        case clang::tok::l_square:
        case clang::tok::l_paren:
        case clang::tok::l_brace:
            ++ParensLevel;
            break;
        case clang::tok::r_square:
        case clang::tok::r_paren:
        case clang::tok::r_brace:
            --ParensLevel;
            if (ParensLevel < 0)
                return {};
            break;
        case clang::tok::comma:
            if (ParensLevel > 0)
                break;
            Result += ",";
            Consume();
            return Result + parseTemplateType();

        case clang::tok::kw_const:
            if (MoveConstToFront) {
                HasConst = true;
                continue;
            }
            break;
        case clang::tok::kw_unsigned:
            if (IsIdentChar(Result[Result.size()]))
                Result+=" ";
            Result += parseUnsigned();
            continue;
        case clang::tok::amp:
        case clang::tok::ampamp:
        case clang::tok::star:
            MoveConstToFront = false;
            break;
        case clang::tok::identifier: {
            clang::LookupResult Found(Sema, CurrentTok.getIdentifierInfo(), OriginalLocation(CurrentTok.getLocation()),
                                      clang::Sema::LookupNestedNameSpecifierName);
            Sema.LookupParsedName(Found, Sema.getScopeForContext(RD), &SS);
            clang::CXXRecordDecl* D = Found.getAsSingle<clang::CXXRecordDecl>();
            if (D && !D->hasDefinition())
                IsPossiblyForwardDeclared = true;
            Found.suppressDiagnostics();
            break;
          }
        case clang::tok::coloncolon:
            if (PrevToken.getIdentifierInfo())
                SS.Extend(Sema.getASTContext(), PrevToken.getIdentifierInfo(), OriginalLocation(), OriginalLocation(CurrentTok.getLocation()));
            break;
        }

        Consume();
        auto Sp = Spelling();
        char Last = Result[Result.size()];
        if ((Last == '<' && Sp[0] == ':') || (IsIdentChar(Last) && IsIdentChar(Sp[0])))
            Result += " ";
        Result += Sp;
    } while (true);
    if (HasConst)
        Result = "const " + Result;
    return Result;
}
Beispiel #13
0
std::string PropertyParser::parseType(bool SupressDiagnostics) {
    std::string Result;
    bool HasConst = Test(clang::tok::kw_const);
    bool HasVolatile = Test(clang::tok::kw_volatile);

    bool NoTemplates = true;

    Test(clang::tok::kw_enum) || Test(clang::tok::kw_class) || Test(clang::tok::kw_struct);

    if (Test(clang::tok::kw_unsigned)) {
        Result += parseUnsigned();
    } else if (Test(clang::tok::kw_signed)) {
        Result += "signed";
        while (true) {
            switch(+CurrentTok.getKind()) {
            case clang::tok::kw_int:
            case clang::tok::kw_long:
            case clang::tok::kw_short:
            case clang::tok::kw_char:
                Consume();
                Result += " " + Spelling();
                continue;
            }
            break;
        }
    } else {
        while(Test(clang::tok::kw_int)
                || Test(clang::tok::kw_long)
                || Test(clang::tok::kw_short)
                || Test(clang::tok::kw_char)
                || Test(clang::tok::kw_void)
                || Test(clang::tok::kw_bool)
                || Test(clang::tok::kw_double)
                || Test(clang::tok::kw_float)) {
            if (!Result.empty())
                Result += " ";
            Result += Spelling();
        }
    }

    if (Result.empty()) {
        clang::CXXScopeSpec SS;
        if (Test(clang::tok::coloncolon)) {
            SS.MakeGlobal(Sema.getASTContext(), OriginalLocation());
            Result += Spelling();
        } do {
            if (!Test(clang::tok::identifier)) {
                PP.getDiagnostics().Report(OriginalLocation(CurrentTok.getLocation()),
                                           PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                                           "Invalid token while parsing type"));
                return {};
            }
            Result += Spelling();

            if (Test(clang::tok::less)) {
                NoTemplates = false;
                Result += "<";
                Result += parseTemplateType();

                if (!PrevToken.is(clang::tok::greater)) {
                    PP.getDiagnostics().Report(OriginalLocation(CurrentTok.getLocation()),
                                               PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
                                               "parse error in type"));
                    return {}; //error;
                }
            }

            clang::Token IdentTok = PrevToken;

            if (!Test(clang::tok::coloncolon))
                break;

            if (NoTemplates && !SupressDiagnostics) {
                if (Sema.ActOnCXXNestedNameSpecifier(Sema.getScopeForContext(RD), *IdentTok.getIdentifierInfo(),
                    OriginalLocation(IdentTok.getLocation()), OriginalLocation(CurrentTok.getLastLoc()), {}, false, SS))
                        SS.SetInvalid({OriginalLocation(IdentTok.getLocation()), OriginalLocation(CurrentTok.getLastLoc())});
            }

            Result += Spelling();
        } while (true);

        if (NoTemplates && !SupressDiagnostics) {

            IsEnum = true; // That's how moc does it.

            if (SS.isNotEmpty() && SS.isValid()) {
                Extra = llvm::dyn_cast_or_null<clang::CXXRecordDecl>(Sema.computeDeclContext(SS));

                clang::LookupResult Found(Sema, PrevToken.getIdentifierInfo(), OriginalLocation(),
                                        clang::Sema::LookupNestedNameSpecifierName);
                /*if (SS.isEmpty())
                    Sema.LookupQualifiedName(Found, RD);
                else {*/
                clang::DeclContext* DC = Sema.computeDeclContext(SS);
                Sema.LookupQualifiedName(Found, DC ? DC : RD);
                //}
                clang::EnumDecl* R = Found.getAsSingle<clang::EnumDecl>();
                /*if (!R) {
                if (clang::TypedefDecl *TD = Found.getAsSingle<clang::TypedefDecl>()) {
                    const clang::TemplateSpecializationType* TDR = TD->getUnderlyingType()->getAs<clang::TemplateSpecializationType>();
                    if(TDR && TDR->getNumArgs() == 1 && TDR->getTemplateName().getAsTemplateDecl()->getName() == "QFlags") {
                        if (const clang::EnumType* ET = TDR->getArg(0).getAsType()->getAs<clang::EnumType>())
                            R = ET->getDecl();
                    }
                }*/

                /*if (!R)
                    IsEnum = false;*/

                if(Extra) {
                    bool isQObjectOrQGadget = false;
                    for (auto it = Extra->decls_begin(); it != Extra->decls_end(); ++it) {
                        auto ND = llvm::dyn_cast<clang::NamedDecl>(*it);
                        if (ND && ND->getIdentifier() && ND->getName() == "staticMetaObject") {
                            isQObjectOrQGadget = true;
                            break;
                        }
                    }
                    if (!isQObjectOrQGadget)
                        Extra = nullptr;
                }

                if (!R) {
                    clang::CXXRecordDecl* D = Found.getAsSingle<clang::CXXRecordDecl>();
                    if (D && !D->hasDefinition())
                        IsPossiblyForwardDeclared = true;
                }
            } else if (SS.isEmpty()) {
                clang::LookupResult Found(Sema, PrevToken.getIdentifierInfo(), OriginalLocation(),
                                          clang::Sema::LookupNestedNameSpecifierName);
                Sema.LookupName(Found, Sema.getScopeForContext(RD));
                clang::CXXRecordDecl* D = Found.getAsSingle<clang::CXXRecordDecl>();
                if (D && !D->hasDefinition()) {
                    IsPossiblyForwardDeclared = true;
                }
                Found.suppressDiagnostics();
            }
        }
    }

    if (NoTemplates && Test(clang::tok::kw_const)) {
        // The official moc don't move the const if there are templates
        HasConst = true;
    }

    while (Test(clang::tok::kw_volatile)
            || Test(clang::tok::star)
            || Test(clang::tok::kw_const)) {
        Extra = nullptr;
        IsEnum = false;
        Result += Spelling();
    }

    if (Test(clang::tok::amp)) {
        if (HasConst)
            HasConst = false; // remove const reference
        else
            Result += Spelling();
    } else {
        Test(clang::tok::ampamp); // skip rvalue ref
    }


    if (HasVolatile)
        Result = "volatile " + Result;
    if (HasConst)
        Result = "const " + Result;

    return Result;
}
Beispiel #14
0
void Service::GetParams(xmlNodePtr n)
{
  xmlChar* s=xmlNodeGetContent(n);
  string v;
  if(s){
    v = (char*)s;
    xmlFree(s);
  }
  if(!xmlStrcmp(n->name, BAD_CAST "label")) {
    // careful, UTF-8, max 16 visible characters!
    service_label = v;
  }
  if(!xmlStrcmp(n->name,BAD_CAST "service_identifier")) {                               
    parseHexBinary(n, "service_identifier", service_identifier);
    size_t len=service_identifier.size();
    if(len>3)
      misconfiguration=true;
    if(len<3){
      bytev::iterator theIterator = service_identifier.begin();
      service_identifier.insert( theIterator, 3-len, 0);
    }
  }
  if(!xmlStrcmp(n->name,BAD_CAST "country")) {
    country = v;
    if(country.size()!=2)
      misconfiguration=true;
  }
  parseUnsigned(n, "language", &language);
  if(!xmlStrcmp(n->name,BAD_CAST "language_long")) {
    language_long = v;
    if(language_long.size()!=3)
      misconfiguration=true;
  }
  parseUnsigned(n, "service_descriptor", &service_descriptor);
  if(!xmlStrcmp(n->name,BAD_CAST "conditional_access")) {
 	for(xmlNodePtr d=n->children; d; d=d->next){
      if(d->type==XML_ELEMENT_NODE){
        parseUnsigned(d, "ca_system_identifer", &ca_system_identifier);
        parseHexBinary(d, "ca_data", ca_data);
        /* TODO (jfbc#2#): ca data can't be more than 126 bytes - check */
      }
    }
  }
  parseIDREF(n, "audio_ref", audio_ref);
  parseIDREF(n, "data_ref", data_ref);
  if(xmlStrEqual(n->name,BAD_CAST "afs_refs")) {
 	for(xmlNodePtr d=n->children; d; d=d->next){
      if(d->type==XML_ELEMENT_NODE){
        string r;
        parseIDREF(d, "afs_ref", r);
        afs_ref.push_back(r);
      }
    }
  }
  if(xmlStrEqual(n->name,BAD_CAST "announcements")) {
 	for(xmlNodePtr d=n->children; d; d=d->next){
      if(d->type==XML_ELEMENT_NODE){
        Announcement a;
        a.ReConfigure(d);
        announcement.push_back(a);
      }
    }
  }
}
Beispiel #15
0
Options::Status Options::parse(int argc, const char **argv) {
    bool test = false;
    bool recursive = false;
    bool ultra = false;
    bool forceStdout = false;
    // Local copy of input files, which are pointers into argv.
    std::vector<const char *> localInputFiles;
    for (int i = 1; i < argc; ++i) {
        const char *arg = argv[i];
        // Protect against empty arguments
        if (arg[0] == 0) {
            continue;
        }
        // Everything after "--" is an input file
        if (!std::strcmp(arg, "--")) {
            ++i;
            std::copy(argv + i, argv + argc, std::back_inserter(localInputFiles));
            break;
        }
        // Long arguments that don't have a short option
        {
            bool isLongOption = true;
            if (!std::strcmp(arg, "--rm")) {
                keepSource = false;
            } else if (!std::strcmp(arg, "--ultra")) {
                ultra = true;
                maxWindowLog = 0;
            } else if (!std::strcmp(arg, "--no-check")) {
                checksum = false;
            } else if (!std::strcmp(arg, "--sparse")) {
                writeMode = WriteMode::Sparse;
                notSupported("Sparse mode");
                return Status::Failure;
            } else if (!std::strcmp(arg, "--no-sparse")) {
                writeMode = WriteMode::Regular;
                notSupported("Sparse mode");
                return Status::Failure;
            } else if (!std::strcmp(arg, "--dictID")) {
                notSupported(arg);
                return Status::Failure;
            } else if (!std::strcmp(arg, "--no-dictID")) {
                notSupported(arg);
                return Status::Failure;
            } else {
                isLongOption = false;
            }
            if (isLongOption) {
                continue;
            }
        }
        // Arguments with a short option simply set their short option.
        const char *options = nullptr;
        if (!std::strcmp(arg, "--processes")) {
            options = "p";
        } else if (!std::strcmp(arg, "--version")) {
            options = "V";
        } else if (!std::strcmp(arg, "--help")) {
            options = "h";
        } else if (!std::strcmp(arg, "--decompress")) {
            options = "d";
        } else if (!std::strcmp(arg, "--force")) {
            options = "f";
        } else if (!std::strcmp(arg, "--stdout")) {
            options = "c";
        } else if (!std::strcmp(arg, "--keep")) {
            options = "k";
        } else if (!std::strcmp(arg, "--verbose")) {
            options = "v";
        } else if (!std::strcmp(arg, "--quiet")) {
            options = "q";
        } else if (!std::strcmp(arg, "--check")) {
            options = "C";
        } else if (!std::strcmp(arg, "--test")) {
            options = "t";
        } else if (arg[0] == '-' && arg[1] != 0) {
            options = arg + 1;
        } else {
            localInputFiles.emplace_back(arg);
            continue;
        }
        assert(options != nullptr);

        bool finished = false;
        while (!finished && *options != 0) {
            // Parse the compression level
            if (*options >= '0' && *options <= '9') {
                compressionLevel = parseUnsigned(&options);
                continue;
            }

            switch (*options) {
            case 'h':
            case 'H':
                usage();
                return Status::Message;
            case 'V':
                std::fprintf(stderr, "PZSTD version: %s.\n", ZSTD_VERSION_STRING);
                return Status::Message;
            case 'p': {
                finished = true;
                const char *optionArgument = getArgument(options, argv, i, argc);
                if (optionArgument == nullptr) {
                    return Status::Failure;
                }
                if (*optionArgument < '0' || *optionArgument > '9') {
                    std::fprintf(stderr, "Option -p expects a number, but %s provided\n",
                                 optionArgument);
                    return Status::Failure;
                }
                numThreads = parseUnsigned(&optionArgument);
                if (*optionArgument != 0) {
                    std::fprintf(stderr,
                                 "Option -p expects a number, but %u%s provided\n",
                                 numThreads, optionArgument);
                    return Status::Failure;
                }
                break;
            }
            case 'o': {
                finished = true;
                const char *optionArgument = getArgument(options, argv, i, argc);
                if (optionArgument == nullptr) {
                    return Status::Failure;
                }
                outputFile = optionArgument;
                break;
            }
            case 'C':
                checksum = true;
                break;
            case 'k':
                keepSource = true;
                break;
            case 'd':
                decompress = true;
                break;
            case 'f':
                overwrite = true;
                forceStdout = true;
                break;
            case 't':
                test = true;
                decompress = true;
                break;
#ifdef UTIL_HAS_CREATEFILELIST
            case 'r':
                recursive = true;
                break;
#endif
            case 'c':
                outputFile = kStdOut;
                forceStdout = true;
                break;
            case 'v':
                ++verbosity;
                break;
            case 'q':
                --verbosity;
                // Ignore them for now
                break;
            // Unsupported options from Zstd
            case 'D':
            case 's':
                notSupported("Zstd dictionaries.");
                return Status::Failure;
            case 'b':
            case 'e':
            case 'i':
            case 'B':
                notSupported("Zstd benchmarking options.");
                return Status::Failure;
            default:
                std::fprintf(stderr, "Invalid argument: %s\n", arg);
                return Status::Failure;
            }
            if (!finished) {
                ++options;
            }
        } // while (*options != 0);
    }   // for (int i = 1; i < argc; ++i);

    // Input file defaults to standard input if not provided.
    if (localInputFiles.empty()) {
        localInputFiles.emplace_back(kStdIn);
    }

    // Check validity of input files
    if (localInputFiles.size() > 1) {
        const auto it = std::find(localInputFiles.begin(), localInputFiles.end(),
                                  std::string{kStdIn});
        if (it != localInputFiles.end()) {
            std::fprintf(
                stderr,
                "Cannot specify standard input when handling multiple files\n");
            return Status::Failure;
        }
    }
    if (localInputFiles.size() > 1 || recursive) {
        if (!outputFile.empty() && outputFile != nullOutput) {
            std::fprintf(
                stderr,
                "Cannot specify an output file when handling multiple inputs\n");
            return Status::Failure;
        }
    }

    // Translate input files/directories into files to (de)compress
    if (recursive) {
        char *scratchBuffer = nullptr;
        unsigned numFiles = 0;
        const char **files =
            UTIL_createFileList(localInputFiles.data(), localInputFiles.size(),
                                &scratchBuffer, &numFiles);
        if (files == nullptr) {
            std::fprintf(stderr, "Error traversing directories\n");
            return Status::Failure;
        }
        auto guard =
            makeScopeGuard([&] { UTIL_freeFileList(files, scratchBuffer); });
        if (numFiles == 0) {
            std::fprintf(stderr, "No files found\n");
            return Status::Failure;
        }
        inputFiles.resize(numFiles);
        std::copy(files, files + numFiles, inputFiles.begin());
    } else {
        inputFiles.resize(localInputFiles.size());
        std::copy(localInputFiles.begin(), localInputFiles.end(),
                  inputFiles.begin());
    }
    localInputFiles.clear();
    assert(!inputFiles.empty());

    // If reading from standard input, default to standard output
    if (inputFiles[0] == kStdIn && outputFile.empty()) {
        assert(inputFiles.size() == 1);
        outputFile = "-";
    }

    if (inputFiles[0] == kStdIn && IS_CONSOLE(stdin)) {
        assert(inputFiles.size() == 1);
        std::fprintf(stderr, "Cannot read input from interactive console\n");
        return Status::Failure;
    }
    if (outputFile == "-" && IS_CONSOLE(stdout) && !(forceStdout && decompress)) {
        std::fprintf(stderr, "Will not write to console stdout unless -c or -f is "
                     "specified and decompressing\n");
        return Status::Failure;
    }

    // Check compression level
    {
        unsigned maxCLevel =
            ultra ? ZSTD_maxCLevel() : kMaxNonUltraCompressionLevel;
        if (compressionLevel > maxCLevel || compressionLevel == 0) {
            std::fprintf(stderr, "Invalid compression level %u.\n", compressionLevel);
            return Status::Failure;
        }
    }

    // Check that numThreads is set
    if (numThreads == 0) {
        std::fprintf(stderr, "Invalid arguments: # of threads not specified "
                     "and unable to determine hardware concurrency.\n");
        return Status::Failure;
    }

    // Modify verbosity
    // If we are piping input and output, turn off interaction
    if (inputFiles[0] == kStdIn && outputFile == kStdOut && verbosity == 2) {
        verbosity = 1;
    }
    // If we are in multi-file mode, turn off interaction
    if (inputFiles.size() > 1 && verbosity == 2) {
        verbosity = 1;
    }

    // Set options for test mode
    if (test) {
        outputFile = nullOutput;
        keepSource = true;
    }
    return Status::Success;
}