void fuzzy_time_to_words(int hours, int minutes, char* words, size_t length) { int fuzzy_hours = hours; int fuzzy_minutes = ((minutes + 2) / 5) * 5; // Handle hour & minute roll-over. if (fuzzy_minutes > 55) { fuzzy_minutes = 0; fuzzy_hours += 1; if (fuzzy_hours > 23) { fuzzy_hours = 0; } } size_t remaining = length; memset(words, 0, length); if (fuzzy_minutes != 0 && (fuzzy_minutes >= 10 || fuzzy_minutes == 5 || fuzzy_hours == 0 || fuzzy_hours == 12)) { if (fuzzy_minutes == 15) { remaining -= append_hour(words, remaining, fuzzy_hours); remaining -= append_string(words, remaining, " "); remaining -= append_string(words, remaining, STR_AND); remaining -= append_string(words, remaining, " "); remaining -= append_string(words, remaining, STR_QUARTER); } else if (fuzzy_minutes == 45) { remaining -= append_string(words, remaining, STR_QUARTER); remaining -= append_string(words, remaining, " "); remaining -= append_string(words, remaining, STR_TO); remaining -= append_string(words, remaining, " "); fuzzy_hours = (fuzzy_hours + 1) % 24; remaining -= append_hour(words, remaining, fuzzy_hours); } else if (fuzzy_minutes == 30) { remaining -= append_string(words, remaining, STR_HALF); remaining -= append_string(words, remaining, " "); fuzzy_hours = (fuzzy_hours + 1) % 24; remaining -= append_hour(words, remaining, fuzzy_hours); } else if (fuzzy_minutes < 30) { remaining -= append_hour(words, remaining, fuzzy_hours); remaining -= append_string(words, remaining, " "); remaining -= append_string(words, remaining, STR_AND); remaining -= append_string(words, remaining, " "); remaining -= append_number(words, fuzzy_minutes); } else { remaining -= append_number(words, 60 - fuzzy_minutes); remaining -= append_string(words, remaining, " "); remaining -= append_string(words, remaining, STR_TO); remaining -= append_string(words, remaining, " "); fuzzy_hours = (fuzzy_hours + 1) % 24; remaining -= append_hour(words, remaining, fuzzy_hours); } } if (fuzzy_minutes == 0 && (fuzzy_hours == 0 || fuzzy_hours == 12)) { remaining -= append_hour(words, remaining, fuzzy_hours); } if (fuzzy_minutes == 0 && !(fuzzy_hours == 0 || fuzzy_hours == 12)) { fuzzy_hours = fuzzy_hours; remaining -= append_number(words, fuzzy_hours); remaining -= append_string(words, remaining, " "); if (fuzzy_hours==1) { remaining -= append_string(words, remaining, STR_OH_CLOCK); } else if (fuzzy_hours<5) { remaining -= append_string(words, remaining, STR_OH_MCLOCK); } else { remaining -= append_string(words, remaining, STR_OH_PCLOCK); } } }
tfs_token_array_t *tfs_posix_parse(const char *bytes, tfs_handle_string_callback handle_error, tfs_error_e *outError) { tfs_token_array_t *tokens = tfs_init_token_array(10); tfs_token_t *new_token = NULL; int literal_len = 0; const char *p = bytes; while (*p) { if (*p == '%') { if (literal_len) { new_token = tfs_append_token(tokens); new_token->is_literal = 1; if (literal_len > sizeof(new_token->text)) literal_len = sizeof(new_token->text); memcpy(new_token->text, p-literal_len, literal_len); literal_len = 0; } p++; if (*p == '\0') { *outError = TFS_PARSE_ERROR; tfs_free_token_array(tokens); return NULL; } if (*p == 'n' || *p == 't' || *p == '%') { new_token = tfs_append_token(tokens); new_token->is_literal = 1; if (*p == 'n') { new_token->text[0] = '\n'; } else if (*p == 't') { new_token->text[0] = '\t'; } else { new_token->text[0] = *p; } } else if (*p == 'D') { new_token = append_month(tokens, TFS_2DIGIT); new_token = append_literal_char(tokens, '/'); new_token = append_day(tokens, TFS_MONTH, TFS_2DIGIT); new_token = append_literal_char(tokens, '/'); new_token = append_year(tokens, TFS_CENTURY, TFS_2DIGIT); } else if (*p == 'F') { new_token = append_year(tokens, TFS_ERA, TFS_NUMBER); new_token = append_literal_char(tokens, '-'); new_token = append_month(tokens, TFS_2DIGIT); new_token = append_literal_char(tokens, '-'); new_token = append_day(tokens, TFS_MONTH, TFS_2DIGIT); } else if (*p == 'R') { new_token = append_hour(tokens, TFS_DAY, TFS_2DIGIT); new_token = append_literal_char(tokens, ':'); new_token = append_minute(tokens, TFS_HOUR, TFS_2DIGIT); } else if (*p == 'r') { new_token = append_hour(tokens, TFS_PERIOD, TFS_2DIGIT); new_token = append_literal_char(tokens, ':'); new_token = append_minute(tokens, TFS_HOUR, TFS_2DIGIT); new_token = append_literal_char(tokens, ':'); new_token = append_second(tokens, TFS_MINUTE, TFS_2DIGIT); new_token = append_literal_char(tokens, ' '); new_token = append_ampm(tokens, TFS_ABBREV); } else if (*p == 'T') { new_token = append_hour(tokens, TFS_DAY, TFS_2DIGIT); new_token = append_literal_char(tokens, ':'); new_token = append_minute(tokens, TFS_HOUR, TFS_2DIGIT); new_token = append_literal_char(tokens, ':'); new_token = append_second(tokens, TFS_MINUTE, TFS_2DIGIT); } else if (*p == 'v') { new_token = append_day(tokens, TFS_MONTH, TFS_NUMBER); new_token = append_literal_char(tokens, '-'); new_token = append_month(tokens, TFS_ABBREV); new_token = append_literal_char(tokens, '-'); new_token = append_year(tokens, TFS_ERA, TFS_NUMBER); } else { int i; for (i=0; i<sizeof(posix_tokens)/sizeof(posix_tokens[0]); i++) { if (posix_tokens[i].text[1] == *p) { new_token = tfs_append_token(tokens); memcpy(new_token, &posix_tokens[i].token, sizeof(tfs_token_t)); break; } } if (i == sizeof(posix_tokens)/sizeof(posix_tokens[0])) { if (handle_error) { char error_buf[1024]; snprintf(error_buf, sizeof(error_buf), "Unrecognized percent code: %c", *p); handle_error(error_buf, sizeof(error_buf), tokens); } *outError = TFS_PARSE_ERROR; tfs_free_token_array(tokens); return NULL; } } } else { literal_len++; } p++; } if (literal_len) { new_token = tfs_append_token(tokens); new_token->is_literal = 1; if (literal_len > sizeof(new_token->text)) literal_len = sizeof(new_token->text); memcpy(new_token->text, p-literal_len, literal_len); } return tokens; }