| 3965 | } while (lowerit(*word++) != lowerit(*abbr)); |
| 3966 | return true; |
| 3967 | } |
| 3968 | |
| 3969 | /* Return true if ABBR is an initial prefix of WORD, ignoring ASCII case. */ |
| 3970 | |
| 3971 | ATTRIBUTE_PURE_114833 |
| 3972 | static bool |
| 3973 | ciprefix(char const *abbr, char const *word) |
| 3974 | { |
| 3975 | do |
| 3976 | if (!*abbr) |
| 3977 | return true; |
| 3978 | while (lowerit(*abbr++) == lowerit(*word++)); |
| 3979 | |
| 3980 | return false; |
| 3981 | } |
| 3982 | |
| 3983 | static const struct lookup * |
| 3984 | byword(const char *word, const struct lookup *table) |
| 3985 | { |
| 3986 | register const struct lookup * foundlp; |
| 3987 | register const struct lookup * lp; |
| 3988 | |
| 3989 | if (word == NULL || table == NULL) |
| 3990 | return NULL; |
| 3991 | |
| 3992 | /* If TABLE is LASTS and the word starts with "last" followed |
| 3993 | by a non-'-', skip the "last" and look in WDAY_NAMES instead. |
| 3994 | Warn about any usage of the undocumented prefix "last-". */ |
| 3995 | if (table == lasts && ciprefix("last", word) && word[4]) { |
| 3996 | if (word[4] == '-') |
| 3997 | warning(N_("\"%s\" is undocumented; use \"last%s\" instead"), |
| 3998 | word, word + 5); |
| 3999 | else { |
| 4000 | word += 4; |
| 4001 | table = wday_names; |
| 4002 | } |
| 4003 | } |
| 4004 | |
| 4005 | /* |
| 4006 | ** Look for exact match. |
| 4007 | */ |
| 4008 | for (lp = table; lp->l_word != NULL; ++lp) |
| 4009 | if (ciequal(word, lp->l_word)) |
| 4010 | return lp; |
| 4011 | /* |
| 4012 | ** Look for inexact match. |
| 4013 | */ |
| 4014 | foundlp = NULL; |
| 4015 | for (lp = table; lp->l_word != NULL; ++lp) |
| 4016 | if (ciprefix(word, lp->l_word)) { |
| 4017 | if (foundlp == NULL) |
| 4018 | foundlp = lp; |
| 4019 | else return NULL; /* multiple inexact matches */ |
| 4020 | } |
| 4021 | |
| 4022 | if (foundlp && noise) { |
| 4023 | /* Warn about any backward-compatibility issue with pre-2017c zic. */ |