/* $Id: ttos.c,v 1.9 2008/11/13 02:19:32 ksb Exp $ * Mike's time string abstraction, who knows which version */ #include #include #include #include #include struct sTimeStr { char *pcStr; int iSize; }; #define YEAR (31536000) #define DAY (86400) #define HOUR (3600) #define MINUTE (60) #define SECOND (1) struct sTimeStr aTimes[] = { {"years", YEAR}, {"lyears", YEAR+DAY}, {"leapyears", YEAR+DAY}, {"fortnights", 14*DAY}, {"weeks", 7*DAY}, {"days", DAY}, {"hours", HOUR}, {"minutes", MINUTE}, {"seconds", SECOND }, {NULL, -1 } }; /* (mm) */ char * EatWhite(pcStr) char *pcStr; { while ('\000' != *pcStr && isascii(*pcStr) && isspace(*pcStr)) { pcStr++; } return pcStr; } /* (mm) */ char * EatNumber(pcStr) char *pcStr; { if ('+' == *pcStr || '-' == *pcStr) { ++pcStr; } while ('\000' != *pcStr && isascii(*pcStr) && isdigit(*pcStr)) { pcStr++; } return pcStr; } /* (mm) */ char * EatAlpha(pcStr) char *pcStr; { while ('\000' != *pcStr && isascii(*pcStr) && isalpha(*pcStr)) { pcStr++; } return pcStr; } /* (mm) */ char * DownCase(pcStr) char *pcStr; { static char acRet[16]; /* 11 is the max lenght of aTimes->pcStr */ int iCnt; acRet[0] = '\000'; for ( iCnt=0; iCnt < sizeof(acRet); iCnt++ ) { if ( '\000' == *pcStr ) { acRet[iCnt] = '\000'; return acRet; } if (isascii(*pcStr) && isalpha(*pcStr) && isupper(*pcStr)){ acRet[iCnt] = tolower(*pcStr); } else { acRet[iCnt] = *pcStr; } pcStr++; } return acRet; } /* convert a time to second, could be negative (mm) * return 0 for failed, 1 for success */ int TimeToSeconds(pcStr, piTime) char *pcStr; time_t *piTime; { register int iTotal, iTmp, iTypeLen, iSign; char *pcNum, *pcType; struct sTimeStr *pTmp; iTotal = 0; iSign = 1; while ( '\000' != *pcStr ) { pcNum = EatWhite(pcStr); switch (*pcNum) { case '-': iSign = -1; ++pcNum; break; case '+': iSign = 1; ++pcNum; break; default: break; } if ('\000' == *pcNum || !isascii(*pcNum) || !isdigit(*pcNum) ){ return 0; } pcType = EatWhite(EatNumber(pcStr)); if ( '\000' == *pcType || !isascii(*pcType) || !isalpha(*pcType) ){ return 0; } pcStr = EatAlpha(pcType); iTypeLen = pcStr - pcType; if ( iTypeLen <= 0 ) { return 0; } for ( pTmp = aTimes; pTmp->pcStr; pTmp++ ) { if ( 0 == strncmp(pTmp->pcStr, DownCase(pcType), iTypeLen) ){ iTmp = atoi(pcNum); iTotal += iTmp * pTmp->iSize; break; } } if ( NULL == pTmp->pcStr ) { return 0; } pcStr = EatWhite(pcStr); } *piTime = iSign * iTotal; return 1; } /* Obvious to a C programmer that knows how a boolean evaluates (mm) */ char * Plural(long iNum) { return (1 == iNum) + "s"; } /* (mm) */ char * SecondsToTime(iSeconds) time_t iSeconds; { static char acBuf[1024]; register char *pcBuf; register int iYears, iDays, iHours, iMinutes; pcBuf = acBuf; /* * If iSeconds is 0 from the start, print "0 seconds", else * Don't print 0 values. */ if ( 0 == iSeconds ) { strcpy(pcBuf, "0 Seconds"); return acBuf; } if ( iSeconds < 0 ) { iSeconds *= -1; sprintf(pcBuf, "(negative) "); pcBuf = pcBuf + strlen(pcBuf); } iYears = iSeconds/YEAR; if ( iYears ) { sprintf(pcBuf, "%d Year%s ", iYears, Plural(iYears)); pcBuf = pcBuf + strlen(pcBuf); iSeconds -= (iYears*YEAR); } iDays = iSeconds/DAY; if ( iDays ) { sprintf(pcBuf, "%d Day%s ", iDays, Plural(iDays)); pcBuf = pcBuf + strlen(pcBuf); iSeconds -= (iDays*DAY); } iHours = iSeconds/HOUR; if ( iHours ) { sprintf(pcBuf, "%d Hour%s ", iHours, Plural(iHours)); pcBuf = pcBuf + strlen(pcBuf); iSeconds -= (iHours*HOUR); } iMinutes = iSeconds/MINUTE; if ( iMinutes ) { sprintf(pcBuf, "%d Minute%s ", iMinutes, Plural(iMinutes)); pcBuf = pcBuf + strlen(pcBuf); iSeconds -= (iMinutes*MINUTE); } if ( iSeconds ) { sprintf(pcBuf, "%ld Second%s ", (long)iSeconds, Plural(iSeconds)); } acBuf[strlen(acBuf)] = '\000'; /* Remove trailing space */ return acBuf; } #ifdef TEST /* (mm) */ int main(argc, argv) int argc; char **argv; { auto char acLine[1024]; register int iCnt; auto int iTmp; acLine[0] = '\000'; for (iCnt=1; iCnt <= argc && argv[iCnt]; ++iCnt) { strcat(acLine, argv[iCnt]); strcat(acLine, " "); } if (TimeToSeconds(acLine, & iTmp)) { printf("TimeToSeconds(\"%s\") = %d\n", acLine, iTmp); printf("SecondsToTime(%d) = %s\n", iTmp, SecondsToTime(iTmp)); } else { printf("TimeToSeconds(\"%s\") failed\n", acLine); } return 0; } #endif /* test driver */