📄 osutils.cxx
字号:
// Parse the option specification optionLetters = ""; optionNames.SetSize(0); PIntArray canHaveOptionString; PINDEX codeCount = 0; while (*spec != '\0') { if (*spec == '-') optionLetters += ' '; else optionLetters += *spec++; if (*spec == '-') { const char * base = ++spec; while (*spec != '\0' && *spec != '.' && *spec != ':' && *spec != ';') spec++; optionNames[codeCount] = PString(base, spec-base); if (*spec == '.') spec++; } if (*spec == ':' || *spec == ';') { canHaveOptionString.SetSize(codeCount+1); canHaveOptionString[codeCount] = *spec == ':' ? 2 : 1; spec++; } codeCount++; } // Clear and reset size of option information optionCount.SetSize(0); optionCount.SetSize(codeCount); optionString.SetSize(0); optionString.SetSize(codeCount); // Clear parameter indexes parameterIndex.SetSize(0); shift = 0; // Now work through the arguments and split out the options PINDEX param = 0; BOOL hadMinusMinus = FALSE; while (arg < argumentArray.GetSize()) { const PString & argStr = argumentArray[arg]; if (hadMinusMinus || argStr[0] != '-' || argStr[1] == '\0') { // have a parameter string parameterIndex.SetSize(param+1); parameterIndex[param++] = arg; } else if (optionsBeforeParams && parameterIndex.GetSize() > 0) break; else if (argStr == "--") // ALL remaining args are parameters not options hadMinusMinus = TRUE; else if (argStr[1] == '-') ParseOption(optionNames.GetValuesIndex(argStr.Mid(2)), 0, arg, canHaveOptionString); else { for (PINDEX i = 1; i < argStr.GetLength(); i++) if (ParseOption(optionLetters.Find(argStr[i]), i+1, arg, canHaveOptionString)) break; } arg++; } return param > 0;}BOOL PArgList::ParseOption(PINDEX idx, PINDEX offset, PINDEX & arg, const PIntArray & canHaveOptionString){ if (idx == P_MAX_INDEX) { UnknownOption(argumentArray[arg]); return FALSE; } optionCount[idx]++; if (canHaveOptionString[idx] == 0) return FALSE; if (!optionString[idx]) optionString[idx] += '\n'; if (offset != 0 && (canHaveOptionString[idx] == 1 || argumentArray[arg][offset] != '\0')) { optionString[idx] += argumentArray[arg].Mid(offset); return TRUE; } if (++arg >= argumentArray.GetSize()) return FALSE; optionString[idx] += argumentArray[arg]; return TRUE;}PINDEX PArgList::GetOptionCount(char option) const{ return GetOptionCountByIndex(optionLetters.Find(option));}PINDEX PArgList::GetOptionCount(const char * option) const{ return GetOptionCountByIndex(optionNames.GetValuesIndex(PString(option)));}PINDEX PArgList::GetOptionCount(const PString & option) const{ return GetOptionCountByIndex(optionNames.GetValuesIndex(option));}PINDEX PArgList::GetOptionCountByIndex(PINDEX idx) const{ if (idx < optionCount.GetSize()) return optionCount[idx]; return 0;}PString PArgList::GetOptionString(char option, const char * dflt) const{ return GetOptionStringByIndex(optionLetters.Find(option), dflt);}PString PArgList::GetOptionString(const char * option, const char * dflt) const{ return GetOptionStringByIndex(optionNames.GetValuesIndex(PString(option)), dflt);}PString PArgList::GetOptionString(const PString & option, const char * dflt) const{ return GetOptionStringByIndex(optionNames.GetValuesIndex(option), dflt);}PString PArgList::GetOptionStringByIndex(PINDEX idx, const char * dflt) const{ if (idx < optionString.GetSize() && optionString.GetAt(idx) != NULL) return optionString[idx]; if (dflt != NULL) return dflt; return PString();}PString PArgList::GetParameter(PINDEX num) const{ int idx = shift+(int)num; if (idx >= 0 && idx < (int)parameterIndex.GetSize()) return argumentArray[parameterIndex[idx]]; IllegalArgumentIndex(idx); return PString();}void PArgList::Shift(int sh) { shift += sh; if (shift < 0) shift = 0; else if (shift >= (int)parameterIndex.GetSize()) shift = parameterIndex.GetSize() - 1;}void PArgList::IllegalArgumentIndex(PINDEX idx) const{ PError << "attempt to access undefined argument at index " << idx << endl;} void PArgList::UnknownOption(const PString & option) const{ PError << "unknown option \"" << option << "\"\n";}void PArgList::MissingArgument(const PString & option) const{ PError << "option \"" << option << "\" requires argument\n";}///////////////////////////////////////////////////////////////////////////////// PConfigArgsPConfigArgs::PConfigArgs(const PArgList & args) : PArgList(args), sectionName(config.GetDefaultSection()), negationPrefix("no-"){}PINDEX PConfigArgs::GetOptionCount(char option) const{ PINDEX count; if ((count = PArgList::GetOptionCount(option)) > 0) return count; PString stropt = CharToString(option); if (stropt.IsEmpty()) return 0; return GetOptionCount(stropt);}PINDEX PConfigArgs::GetOptionCount(const char * option) const{ return GetOptionCount(PString(option));}PINDEX PConfigArgs::GetOptionCount(const PString & option) const{ // if specified on the command line, use that option PINDEX count = PArgList::GetOptionCount(option); if (count > 0) return count; // if user has specified "no-option", then ignore config file if (PArgList::GetOptionCount(negationPrefix + option) > 0) return 0; return config.HasKey(sectionName, option) ? 1 : 0;}PString PConfigArgs::GetOptionString(char option, const char * dflt) const{ if (PArgList::GetOptionCount(option) > 0) return PArgList::GetOptionString(option, dflt); PString stropt = CharToString(option); if (stropt.IsEmpty()) { if (dflt != NULL) return dflt; return PString(); } return GetOptionString(stropt, dflt);}PString PConfigArgs::GetOptionString(const char * option, const char * dflt) const{ return GetOptionString(PString(option), dflt);}PString PConfigArgs::GetOptionString(const PString & option, const char * dflt) const{ // if specified on the command line, use that option if (PArgList::GetOptionCount(option) > 0) return PArgList::GetOptionString(option, dflt); // if user has specified "no-option", then ignore config file if (PArgList::HasOption(negationPrefix + option)) { if (dflt != NULL) return dflt; return PString(); } return config.GetString(sectionName, option, dflt != NULL ? dflt : "");}void PConfigArgs::Save(const PString & saveOptionName){ if (PArgList::GetOptionCount(saveOptionName) == 0) return; config.DeleteSection(sectionName); for (PINDEX i = 0; i < optionCount.GetSize(); i++) { PString optionName = optionNames[i]; if (optionCount[i] > 0 && optionName != saveOptionName) { if (optionString.GetAt(i) != NULL) config.SetString(sectionName, optionName, optionString[i]); else config.SetBoolean(sectionName, optionName, TRUE); } }}PString PConfigArgs::CharToString(char ch) const{ PINDEX index = optionLetters.Find(ch); if (index == P_MAX_INDEX) return PString(); if (optionNames.GetAt(index) == NULL) return PString(); return optionNames[index];}///////////////////////////////////////////////////////////////////////////////// PProcessstatic PProcess * PProcessInstance;int PProcess::p_argc;char ** PProcess::p_argv;char ** PProcess::p_envp;#ifndef P_PLATFORM_HAS_THREADSstatic BOOL PProcessTerminating = FALSE;#endifPProcess::PProcess(const char * manuf, const char * name, WORD major, WORD minor, CodeStatus stat, WORD build) : manufacturer(manuf), productName(name){ PProcessInstance = this; terminationValue = 0; majorVersion = major; minorVersion = minor; status = stat; buildNumber = build; if (p_argv != 0 && p_argc > 0) { arguments.SetArgs(p_argc-1, p_argv+1); executableFile = PString(p_argv[0]); if (!PFile::Exists(executableFile)) executableFile += ".exe"; if (productName.IsEmpty()) productName = executableFile.GetTitle().ToLower(); } InitialiseProcessThread(); Construct();}int PProcess::_main(void *){ Main(); return terminationValue;}void PProcess::PreInitialise(int c, char ** v, char ** e){ p_argc = c; p_argv = v; p_envp = e;}PProcess & PProcess::Current(){ if (PProcessInstance == NULL) { cerr << "Catastrophic failure, PProcess::Current() = NULL!!\n";#if defined(_MSC_VER) && defined(_DEBUG) __asm int 3;#endif _exit(1); } return *PProcessInstance;}BOOL PProcess::IsInitialised(){ return PProcessInstance != NULL;}PObject::Comparison PProcess::Compare(const PObject & obj) const{ PAssert(obj.IsDescendant(PProcess::Class()), PInvalidCast); return productName.Compare(((const PProcess &)obj).productName);}void PProcess::Terminate(){#ifdef _WINDLL FatalExit(terminationValue);#else#ifndef P_PLATFORM_HAS_THREADS // Can only terminate process from the processes thread if (currentThread == this) exit(terminationValue); else PProcessTerminating = TRUE;#else exit(terminationValue);#endif#endif}PString PProcess::GetThreadName() const{ return GetName(); } void PProcess::SetThreadName(const PString & /*name*/){}PString PProcess::GetVersion(BOOL full) const{ const char * const statusLetter[NumCodeStatuses] = { "alpha", "beta", "pl" }; return psprintf(full && buildNumber != 0 ? "%u.%u%s%u" : "%u.%u", majorVersion, minorVersion, statusLetter[status], buildNumber);}///////////////////////////////////////////////////////////////////////////////// PThreadvoid PThread::PrintOn(ostream & strm) const{ PString name = GetThreadName(); if (name.IsEmpty()) name.sprintf("%s<%08x>", GetClass(), (int)this); strm << name;}PString PThread::GetThreadName() const{ return threadName; } void PThread::SetThreadName(const PString & name){ threadName = name; }#ifndef P_PLATFORM_HAS_THREADSvoid PThread::InitialiseProcessThread(){ basePriority = NormalPriority; // User settable priority dynamicPriority = 0; // Only thing running suspendCount = 0; // Not suspended (would not be a good idea) ClearBlock(); // No I/O blocking function status = Running; // Thread is already running stackBase = NULL; link = this; ((PProcess*)this)->currentThread = this;}PThread::PThread(PINDEX stackSize, AutoDeleteFlag deletion, Priority priorityLevel, const PString & name) : threadName(name){ autoDelete = deletion == AutoDeleteThread; basePriority = priorityLevel; // Threads user settable priority level dynamicPriority = 0; // Run immediately suspendCount = 1; AllocateStack(stackSize); PAssert(stackBase != NULL, "Insufficient near heap for thread"); status = Terminated; // Set to this so Restart() works Restart();}void PThread::Restart(){ if (status != Terminated) // Is already running return; ClearBlock(); // No I/O blocking function PThread * current = Current(); link = current->link; current->link = this; status = Starting;}void PThread::Terminate(){ if (link == this || status == Terminated) return; // Is only thread or already terminated if (status == Running) { status = Terminating; Yield(); // Never returns from here } PThread * prev = PThread::Current(); while (prev->link != this) prev = prev->link; prev->link = link; // Unlink it from the list status = Terminated;}void PThread::WaitForTermination() const{ while (!IsTerminated())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -