void SG_getopt__free(SG_context * pCtx, SG_getopt * pGetopt) { if (!pGetopt) return; SG_STRING_NULLFREE(pCtx, pGetopt->pStringAppName); SG_STRING_NULLFREE(pCtx, pGetopt->pStringCommandName); if (pGetopt->paszArgs) { SG_ERR_CHECK_RETURN( SG_freeStringList(pCtx, (const char ***)&pGetopt->paszArgs, pGetopt->count_args) ); } SG_NULLFREE(pCtx, pGetopt); }
void SG_time__parse(SG_context* pCtx,const char* pszInputString, SG_int64 * pTime, SG_bool bParseToMaximumValidValue) { SG_string * pWorkingStr = NULL; char** splitOnSpaces = NULL; char** splitOnColons = NULL; char** splitOnDashes = NULL; SG_uint32 nCountAfterSplitOnSpaces = 0; SG_uint32 nCountAfterSplitOnDashes = 0; SG_uint32 nCountAfterSplitOnColons = 0; SG_string * pWorkingStringDate = NULL; SG_string * pWorkingStringTime = NULL; time_t resultTicks = 0; struct tm result; SG_ERR_CHECK( SG_STRING__ALLOC__SZ(pCtx, &pWorkingStr, pszInputString) ); //This understands exactly two formats //YYYY-MM-DD // //and //YYYY-MM-DD hh:mm:ss //The local time zone is always assumed. SG_ERR_CHECK( SG_string__split__asciichar(pCtx, pWorkingStr, ' ', 2, &splitOnSpaces, &nCountAfterSplitOnSpaces) ); if (nCountAfterSplitOnSpaces == 1) { //YYYY-M-DD SG_ERR_CHECK( SG_STRING__ALLOC__SZ(pCtx, &pWorkingStringDate, splitOnSpaces[0]) ); SG_ERR_CHECK( SG_string__split__asciichar(pCtx, pWorkingStringDate, '-', 3, &splitOnDashes, &nCountAfterSplitOnDashes) ); if(nCountAfterSplitOnDashes == 3) { SG_uint32 year = 0; SG_uint32 month = 0; SG_uint32 dayOfMonth = 0; SG_ERR_CHECK( SG_uint32__parse(pCtx, &year, splitOnDashes[0]) ); SG_ERR_CHECK( SG_uint32__parse(pCtx, &month, splitOnDashes[1]) ); SG_ERR_CHECK( SG_uint32__parse(pCtx, &dayOfMonth, splitOnDashes[2]) ); if (month<= 0 || month > 12) SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); if (dayOfMonth<= 0 || dayOfMonth > 31) SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); result.tm_year = year - 1900; result.tm_mon = month - 1; result.tm_mday = dayOfMonth; if (bParseToMaximumValidValue == SG_TRUE) { result.tm_hour = 23; result.tm_min = 59; result.tm_sec = 59; } else { result.tm_hour = 0; result.tm_min = 0; result.tm_sec = 0; } } else SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); } else if (nCountAfterSplitOnSpaces == 2) { //YYYY-MM-DD hh:mm:ss //YYYY-M-DD SG_ERR_CHECK( SG_STRING__ALLOC__SZ(pCtx, &pWorkingStringDate, splitOnSpaces[0]) ); SG_ERR_CHECK( SG_string__split__asciichar(pCtx, pWorkingStringDate, '-', 3, &splitOnDashes, &nCountAfterSplitOnDashes) ); if(nCountAfterSplitOnDashes == 3) { SG_uint32 year = 0; SG_uint32 month = 0; SG_uint32 dayOfMonth = 0; SG_ERR_CHECK( SG_uint32__parse(pCtx, &year, splitOnDashes[0]) ); SG_ERR_CHECK( SG_uint32__parse(pCtx, &month, splitOnDashes[1]) ); SG_ERR_CHECK( SG_uint32__parse(pCtx, &dayOfMonth, splitOnDashes[2]) ); if (month<= 0 || month > 12) SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); if (dayOfMonth<= 0 || dayOfMonth > 31) SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); result.tm_year = year - 1900; result.tm_mon = month - 1; result.tm_mday = dayOfMonth; } else SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); SG_ERR_CHECK( SG_STRING__ALLOC__SZ(pCtx, &pWorkingStringTime, splitOnSpaces[1]) ); SG_ERR_CHECK( SG_string__split__asciichar(pCtx, pWorkingStringTime, ':', 3, &splitOnColons, &nCountAfterSplitOnColons) ); if(nCountAfterSplitOnColons == 3) { SG_uint32 hour = 0; SG_uint32 minute = 0; SG_uint32 second = 0; SG_ERR_CHECK( SG_uint32__parse(pCtx, &hour, splitOnColons[0]) ); SG_ERR_CHECK( SG_uint32__parse(pCtx, &minute, splitOnColons[1]) ); SG_ERR_CHECK( SG_uint32__parse(pCtx, &second, splitOnColons[2]) ); if (hour > 23) SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); if (minute > 59) SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); if (second > 59) SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); result.tm_hour = hour; result.tm_min = minute; result.tm_sec = second; } else SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); } else { //Invalid date. SG_ERR_THROW(SG_ERR_DATE_PARSING_ERROR); } result.tm_isdst = -1; resultTicks = mktime(&result); if (resultTicks >= 0) { *pTime = resultTicks; *pTime = *pTime * MILLISECONDS_PER_SECOND; if (bParseToMaximumValidValue == SG_TRUE) { *pTime += 999; } } SG_STRING_NULLFREE(pCtx, pWorkingStringTime); SG_STRING_NULLFREE(pCtx, pWorkingStringDate); if (splitOnColons != NULL) SG_ERR_CHECK( SG_freeStringList(pCtx, (const char ***)&splitOnColons, nCountAfterSplitOnColons) ); if (splitOnSpaces != NULL) SG_ERR_CHECK( SG_freeStringList(pCtx, (const char ***)&splitOnSpaces, nCountAfterSplitOnSpaces) ); if (splitOnDashes != NULL) SG_ERR_CHECK( SG_freeStringList(pCtx, (const char ***)&splitOnDashes, nCountAfterSplitOnDashes) ); SG_STRING_NULLFREE(pCtx, pWorkingStr); return; fail: SG_STRING_NULLFREE(pCtx, pWorkingStringTime); SG_STRING_NULLFREE(pCtx, pWorkingStringDate); if (splitOnColons != NULL && nCountAfterSplitOnColons > 0) SG_ERR_IGNORE( SG_freeStringList(pCtx, (const char ***)&splitOnColons, nCountAfterSplitOnColons) ); if (splitOnSpaces != NULL && nCountAfterSplitOnSpaces > 0) SG_ERR_IGNORE( SG_freeStringList(pCtx, (const char ***)&splitOnSpaces, nCountAfterSplitOnSpaces) ); if (splitOnDashes != NULL) SG_ERR_IGNORE( SG_freeStringList(pCtx, (const char ***)&splitOnDashes, nCountAfterSplitOnDashes) ); SG_STRING_NULLFREE(pCtx, pWorkingStr); return; }