singularize/pluralize decisions common to both makesingular & makeplural */
| 2705 | |
| 2706 | /* singularize/pluralize decisions common to both makesingular & makeplural */ |
| 2707 | staticfn boolean |
| 2708 | singplur_lookup( |
| 2709 | char *basestr, char *endstring, /* base string, pointer to eos(string) */ |
| 2710 | boolean to_plural, /* true => makeplural, false => makesingular */ |
| 2711 | const char *const *alt_as_is) /* another set like as_is[] */ |
| 2712 | { |
| 2713 | const struct sing_plur *sp; |
| 2714 | const char *same, *other, *const *as; |
| 2715 | int al; |
| 2716 | int baselen = Strlen(basestr); |
| 2717 | |
| 2718 | for (as = as_is; *as; ++as) { |
| 2719 | al = (int) strlen(*as); |
| 2720 | if (!BSTRCMPI(basestr, endstring - al, *as)) |
| 2721 | return TRUE; |
| 2722 | } |
| 2723 | if (alt_as_is) { |
| 2724 | for (as = alt_as_is; *as; ++as) { |
| 2725 | al = (int) strlen(*as); |
| 2726 | if (!BSTRCMPI(basestr, endstring - al, *as)) |
| 2727 | return TRUE; |
| 2728 | } |
| 2729 | } |
| 2730 | |
| 2731 | /* Leave "craft" as a suffix as-is (aircraft, hovercraft); |
| 2732 | "craft" itself is (arguably) not included in our likely context */ |
| 2733 | if ((baselen > 5) && (!BSTRCMPI(basestr, endstring - 5, "craft"))) |
| 2734 | return TRUE; |
| 2735 | /* avoid false hit on one_off[].plur == "lice" or .sing == "goose"; |
| 2736 | if more of these turn up, one_off[] entries will need to flagged |
| 2737 | as to which are whole words and which are matchable as suffices |
| 2738 | then matching in the loop below will end up becoming more complex */ |
| 2739 | if (!strcmpi(basestr, "slice") |
| 2740 | || !strcmpi(basestr, "mongoose")) { |
| 2741 | if (to_plural) |
| 2742 | Strcasecpy(endstring, "s"); |
| 2743 | return TRUE; |
| 2744 | } |
| 2745 | /* skip "ox" -> "oxen" entry when pluralizing "<something>ox" |
| 2746 | unless it is muskox */ |
| 2747 | if (to_plural && baselen > 2 && !strcmpi(endstring - 2, "ox") |
| 2748 | && !(baselen > 5 && !strcmpi(endstring - 6, "muskox"))) { |
| 2749 | /* "fox" -> "foxes" */ |
| 2750 | Strcasecpy(endstring, "es"); |
| 2751 | return TRUE; |
| 2752 | } |
| 2753 | if (to_plural) { |
| 2754 | if (baselen > 2 && !strcmpi(endstring - 3, "man") |
| 2755 | && badman(basestr, to_plural)) { |
| 2756 | Strcasecpy(endstring, "s"); |
| 2757 | return TRUE; |
| 2758 | } |
| 2759 | } else { |
| 2760 | if (baselen > 2 && !strcmpi(endstring - 3, "men") |
| 2761 | && badman(basestr, to_plural)) |
| 2762 | return TRUE; |
| 2763 | } |
| 2764 | for (sp = one_off; sp->sing; sp++) { |
no test coverage detected