📄 osutils.cxx
字号:
PArgList::PArgList(int theArgc, char ** theArgv, const char * theArgumentSpec, BOOL optionsBeforeParams){ // get the program arguments SetArgs(theArgc, theArgv); // if we got an argument spec - so process them if (theArgumentSpec != NULL) Parse(theArgumentSpec, optionsBeforeParams);}PArgList::PArgList(int theArgc, char ** theArgv, const PString & theArgumentSpec, BOOL optionsBeforeParams){ // get the program name and path SetArgs(theArgc, theArgv); // we got an argument spec - so process them Parse(theArgumentSpec, optionsBeforeParams);}void PArgList::PrintOn(ostream & strm) const{ for (PINDEX i = 0; i < argumentArray.GetSize(); i++) { if (i > 0) strm << strm.fill(); strm << argumentArray[i]; }}void PArgList::ReadFrom(istream & strm){ PString line; strm >> line; SetArgs(line);}void PArgList::SetArgs(const PString & argStr){ argumentArray.SetSize(0); const char * str = argStr; for (;;) { while (isspace(*str)) // Skip leading whitespace str++; if (*str == '\0') break; PString & arg = argumentArray[argumentArray.GetSize()]; while (*str != '\0' && !isspace(*str)) { switch (*str) { case '"' : str++; while (*str != '\0' && *str != '"') arg += *str++; if (*str != '\0') str++; break; case '\'' : str++; while (*str != '\0' && *str != '\'') arg += *str++; if (*str != '\0') str++; break; default : if (str[0] == '\\' && str[1] != '\0') str++; arg += *str++; } } } SetArgs(argumentArray);}void PArgList::SetArgs(const PStringArray & theArgs){ argumentArray = theArgs; shift = 0; optionLetters = ""; optionNames.SetSize(0); parameterIndex.SetSize(argumentArray.GetSize()); for (PINDEX i = 0; i < argumentArray.GetSize(); i++) parameterIndex[i] = i;}BOOL PArgList::Parse(const char * spec, BOOL optionsBeforeParams){ if (PAssertNULL(spec) == NULL) return FALSE; // Find starting point, start at shift if first Parse() call. PINDEX arg = optionLetters.IsEmpty() ? shift : 0; // If not in parse all mode, have been parsed before, and had some parameters // from last time, then start argument parsing somewhere along instead of start. if (optionsBeforeParams && !optionLetters && parameterIndex.GetSize() > 0) arg = parameterIndex[parameterIndex.GetSize()-1] + 1; // 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();}PStringArray PArgList::GetParameters(PINDEX first, PINDEX last) const{ PStringArray array; last += shift; if (last < 0) return array; if (last >= parameterIndex.GetSize()) last = parameterIndex.GetSize()-1; first += shift; if (first < 0) first = 0; if (first > last) return array; array.SetSize(last-first+1); PINDEX idx = 0; while (first <= last) array[idx++] = argumentArray[parameterIndex[first++]]; return array;}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";}#ifdef P_CONFIG_FILE///////////////////////////////////////////////////////////////////////////////// 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];}#endif // P_CONFIG_ARGS///////////////////////////////////////////////////////////////////////////////// PProcessstatic PProcess * PProcessInstance;int PProcess::p_argc;char ** PProcess::p_argv;char ** PProcess::p_envp;typedef std::map<PString, PProcessStartup *> PProcessStartupList;int PProcess::_main(void *){ Main(); return terminationValue;}void PProcess::PreInitialise(int c, char ** v, char ** e){#if PMEMORY_CHECK PMemoryHeap::SetIgnoreAllocations(FALSE);#endif p_argc = c; p_argv = v; p_envp = e;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -