📄 osutils.cxx
字号:
{
timerList->processingMutex.Wait();
if (IsRunning())
state = Paused;
timerList->processingMutex.Signal();
}
void PTimer::Resume()
{
timerList->processingMutex.Wait();
if (state == Paused)
state = Starting;
timerList->processingMutex.Signal();
}
void PTimer::Reset()
{
timerList->processingMutex.Wait();
StartRunning(oneshot);
}
void PTimer::OnTimeout()
{
if (!callback.IsNULL())
callback(*this, IsRunning());
}
void PTimer::Process(const PTimeInterval & delta, PTimeInterval & minTimeLeft)
{
/*Ideally there should be a processingMutex for each individual timer, but
that seems incredibly profligate of system resources as there can be a
LOT of PTimer instances about. So use one one mutex for all.
*/
timerList->processingMutex.Wait();
switch (state) {
case Starting :
state = Running;
if (resetTime < minTimeLeft)
minTimeLeft = resetTime;
break;
case Running :
operator-=(delta);
if (milliseconds > 0) {
if (milliseconds < minTimeLeft.GetMilliSeconds())
minTimeLeft = *this;
}
else {
if (oneshot) {
milliseconds = 0;
state = Stopped;
}
else {
PTimeInterval::operator=(resetTime);
if (resetTime < minTimeLeft)
minTimeLeft = resetTime;
}
timerList->processingMutex.Signal();
/* This must be outside the mutex or if OnTimeout() changes the
timer value (quite plausible) it deadlocks.
*/
OnTimeout();
return;
}
break;
default : // Stopped or Paused, do nothing.
break;
}
timerList->processingMutex.Signal();
}
///////////////////////////////////////////////////////////////////////////////
// PTimerList
PTimerList::PTimerList()
{
DisallowDeleteObjects();
currentTimer = NULL;
}
PTimeInterval PTimerList::Process()
{
PINDEX i;
PTimeInterval minTimeLeft = PMaxTimeInterval;
listMutex.Wait();
PTimeInterval now = PTimer::Tick();
PTimeInterval sampleTime;
if (lastSample == 0 || lastSample > now)
sampleTime = 0;
else {
sampleTime = now - lastSample;
if (now < lastSample)
sampleTime += PMaxTimeInterval;
}
lastSample = now;
for (i = 0; i < GetSize(); i++) {
currentTimer = (PTimer *)GetAt(i);
inTimeoutMutex.Wait();
listMutex.Signal();
currentTimer->Process(sampleTime, minTimeLeft);
listMutex.Wait();
inTimeoutMutex.Signal();
}
currentTimer = NULL;
listMutex.Signal();
return minTimeLeft;
}
///////////////////////////////////////////////////////////////////////////////
// PArgList
PArgList::PArgList(const char * theArgStr,
const char * theArgumentSpec,
BOOL optionsBeforeParams)
{
// get the program arguments
if (theArgStr != NULL)
SetArgs(theArgStr);
// if we got an argument spec - so process them
if (theArgumentSpec != NULL)
Parse(theArgumentSpec, optionsBeforeParams);
}
PArgList::PArgList(const PString & theArgStr,
const char * argumentSpecPtr,
BOOL optionsBeforeParams)
{
// get the program arguments
SetArgs(theArgStr);
// if we got an argument spec - so process them
if (argumentSpecPtr != NULL)
Parse(argumentSpecPtr, optionsBeforeParams);
}
PArgList::PArgList(const PString & theArgStr,
const PString & argumentSpecStr,
BOOL optionsBeforeParams)
{
// get the program arguments
SetArgs(theArgStr);
// if we got an argument spec - so process them
Parse(argumentSpecStr, optionsBeforeParams);
}
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -