📄 osutils.cxx
字号:
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
///////////////////////////////////////////////////////////////////////////////
// PConfigArgs
PConfigArgs::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
///////////////////////////////////////////////////////////////////////////////
// PProcess
static 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;
}
static PProcessStartupList & GetPProcessStartupList()
{
static PProcessStartupList list;
return list;
}
PProcess::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;
// This flag must never be destroyed before it is finished with. As we
// cannot assure destruction at the right time we simply allocate it and
// NEVER destroy it! This is OK as the only reason for its destruction is
// the program is exiting and then who cares?
#if PMEMORY_CHECK
BOOL ignoreAllocations = PMemoryHeap::SetIgnoreAllocations(TRUE);
#endif
PTraceMutex = new PMutex;
#if PMEMORY_CHECK
PMemoryHeap::SetIgnoreAllocations(ignoreAllocations);
#endif
#ifndef P_RTEMS
if (p_argv != 0 && p_argc > 0) {
arguments.SetArgs(p_argc-1, p_argv+1);
executableFile = PString(p_argv[0]);
if (!PFile::Exists(executableFile)) {
PString execFile = executableFile + ".exe";
if (PFile::Exists(execFile))
executableFile = execFile;
}
if (productName.IsEmpty())
productName = executableFile.GetTitle().ToLower();
}
#else
cout << "Enter program arguments:\n";
arguments.ReadFrom(cin);
#endif
InitialiseProcessThread();
Construct();
#ifdef __MACOSX__
#ifdef HAS_VIDEO
PWLibStupidOSXHacks::loadFakeVideoStuff = 1;
#ifdef USE_SHM_VIDEO_DEVICES
PWLibStupidOSXHacks::loadShmVideoStuff = 1;
#endif // USE_SHM_VIDEO_DEVICES
#endif // HAS_VIDEO
#ifdef HAS_AUDIO
PWLibStupidOSXHacks::loadCoreAudioStuff = 1;
#endif // HAS_AUDIO
#endif // __MACOSX__
// create one instance of each class registered in the
// PProcessStartup abstract factory
PProcessStartupList & startups = GetPProcessStartupList();
{
PProcessStartup * levelSet = PFactory<PProcessStartup>::CreateInstance("SetTraceLevel");
if (levelSet != NULL)
levelSet->OnStartup();
else {
char * env = ::getenv("PWLIB_TRACE_STARTUP");
if (env != NULL)
PTrace::Initialise(atoi(env), NULL, PTrace::Blocks | PTrace::Timestamp | PTrace::Thread | PTrace::FileAndLine);
}
PProcessStartupFactory::KeyList_T list = PProcessStartupFactory::GetKeyList();
PProcessStartupFactory::KeyList_T::const_iterator r;
for (r = list.begin(); r != list.end(); ++r) {
if (*r != "SetTraceLevel") {
PProcessStartup * instance = PProcessStartupFactory::CreateInstance(*r);
instance->OnStartup();
startups.insert(std::pair<PString, PProcessStartup *>(*r, instance));
}
}
}
}
void PProcess::PreShutdown()
{
PProcessStartupList & startups = GetPProcessStartupList();
// call OnShutfdown for the PProcessInstances previously created
// make sure we handle singletons correctly
{
while (startups.size() > 0) {
PProcessStartupList::iterator r = startups.begin();
PProcessStartup * instance = r->second;
instance->OnShutdown();
if (!PProcessStartupFactory::IsSingleton(r->first))
delete instance;
startups.erase(r);
}
}
}
PProcess & PProcess::Current()
{
if (PProcessInstance == NULL) {
cerr << "Catastrophic failure, PProcess::Current() = NULL!!\n";
#if defined(_MSC_VER) && defined(_DEBUG) && !defined(_WIN32_WCE)
__debugbreak();
#endif
_exit(1);
}
return *PProcessInstance;
}
BOOL PProcess::IsInitialised()
{
return PProcessInstance != NULL;
}
PObject::Comparison PProcess::Compare(const PObject & obj) const
{
PAssert(PIsDescendant(&obj, PProcess), PInvalidCast);
return productName.Compare(((const PProcess &)obj).productName);
}
void PProcess::Terminate()
{
#ifdef _WINDLL
FatalExit(terminationValue);
#else
exit(terminationValue);
#endif
}
PString PProcess::GetThreadName() const
{
return GetName();
}
void PProcess::SetThreadName(const PString & /*name*/)
{
}
PTime PProcess::GetStartTime() const
{
return programStartTime;
}
PString PProcess::GetVersion(BOOL full) const
{
const char * const statusLetter[NumCodeStatuses] =
{ "alpha", "beta", "." };
return psprintf(full ? "%u.%u%s%u" : "%u.%u",
majorVersion, minorVersion, statusLetter[status], buildNumber);
}
void PProcess::SetConfigurationPath(const PString & path)
{
configurationPaths = path.Tokenise(";:", FALSE);
}
///////////////////////////////////////////////////////////////////////////////
// PThread
void PThread::PrintOn(ostream & strm) const
{
strm << GetThreadName();
}
PString PThread::GetThreadName() const
{
return threadName;
}
#if defined(_DEBUG) && defined(_MSC_VER)
typedef struct tagTHREADNAME_INFO
{
DWORD dwType ; // must be 0x1000
LPCSTR szName ; // pointer to name (in user addr space)
DWORD dwThreadID ; // thread ID (-1=caller thread, but seems to set more than one thread's name)
DWORD dwFlags ; // reserved for future use, must be zero
} THREADNAME_INFO ;
void SetWinDebugThreadName (THREADNAME_INFO * info)
{
__try
{
RaiseException (0x406D1388, 0, sizeof(THREADNAME_INFO)/sizeof(DWORD), reinterpret_cast<const ULONG_PTR*>(info)) ;
} // if not running under debugger exception comes back
__except(EXCEPTION_CONTINUE_EXECUTION)
{ // just keep on truckin'
}
}
#endif // defined(_DEBUG) && defined(_MSC_VER)
void PThread::SetThreadName(const PString & name)
{
if (name.IsEmpty())
threadName = psprintf("%s:%08x", GetClass(), (INT)this);
else
threadName = psprintf(name, (INT)this);
#if defined(_DEBUG) && defined(_MSC_VER)
if (threadId) { // make thread name known to debugger
THREADNAME_INFO Info = { 0x1000, (const char *) threadName, threadId, 0 } ;
SetWinDebugThreadName (&Info) ;
}
#endif // defined(_DEBUG) && defined(_MSC_VER)
}
PThread * PThread::Create(const PNotifier & notifier,
INT parameter,
AutoDeleteFlag deletion,
Priority priorityLevel,
const PString & threadName,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -