home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / wp_dtp / ispell.lha / good.c < prev    next >
C/C++ Source or Header  |  1990-08-06  |  15KB  |  845 lines

  1. /*
  2.  * good.c - see if a word or its root word
  3.  * is in the dictionary.
  4.  *
  5.  * Pace Willisson, 1983
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10. #include <string.h>
  11. #include <proto/all.h>
  12. #include "config.h"
  13. #include "ispell.h"
  14.  
  15. static int wordok;
  16. static char *orig_word;
  17.  
  18. extern int cflag;
  19.  
  20. int 
  21. good (char *w)
  22. {
  23.   char nword[100];
  24.   register char *p, *q;
  25.   register n;
  26.  
  27.   /*
  28.   ** Make an uppercase copy of the word we are checking.
  29.   */
  30.   for (p = w, q = nword; *p; p++, q++)
  31.     {
  32.       if (mylower (*p))
  33.     *q = toupper (*p);
  34.       else
  35.     *q = *p;
  36.     }
  37.   *q = 0;
  38.  
  39.   rootword[0] = 0;
  40.  
  41.   if (cflag)
  42.     {
  43.       printf ("%s\n", w);
  44.       orig_word = w;
  45.     }
  46.   else if (lookup (nword, q - nword, 1) != NULL)
  47.     {
  48. #ifdef CAPITALIZE
  49.       return cap_ok (w, lastdent);
  50. #else
  51.       return (1);
  52. #endif
  53.     }
  54.  
  55.   /* try stripping off suffixes */
  56.  
  57.   n = strlen (w);
  58.   if (n == 1)
  59.     return (1);
  60.  
  61.   if (n < 4)
  62.     return 0;
  63.  
  64.   wordok = 0;
  65.  
  66.   /* this part from 'check.mid' */
  67.   switch (q[-1])
  68.     {
  69.     case 'D':
  70.       d_ending (nword, n);
  71.       break;            /* FOR "CREATED", "IMPLIED", "CROSSED" */
  72.     case 'T':
  73.       t_ending (nword, n);
  74.       break;            /* FOR "LATEST", "DIRTIEST", "BOLDEST" */
  75.     case 'R':
  76.       r_ending (nword, n);
  77.       break;            /* FOR "LATER", "DIRTIER", "BOLDER" */
  78.     case 'G':
  79.       g_ending (nword, n);
  80.       break;            /* FOR "CREATING", "FIXING" */
  81.     case 'H':
  82.       h_ending (nword, n);
  83.       break;            /* FOR "HUNDREDTH", "TWENTIETH" */
  84.     case 'S':
  85.       s_ending (nword, n);
  86.       break;            /* FOR ALL SORTS OF THINGS ENDING IN "S" */
  87.     case 'N':
  88.       n_ending (nword, n);
  89.       break;            /* "TIGHTEN", "CREATION", "MULIPLICATION" */
  90.     case 'E':
  91.       e_ending (nword, n);
  92.       break;            /* FOR "CREATIVE", "PREVENTIVE" */
  93.     case 'Y':
  94.       y_ending (nword, n);
  95.       break;            /* FOR "QUICKLY" */
  96.     default:
  97.       break;
  98.     }
  99.  
  100.   if (wordok)
  101.     {
  102.       strcpy (rootword, lastdent->word);
  103. #ifdef CAPITALIZE
  104.       return cap_ok (w, lastdent);
  105. #else
  106.       return 1;
  107. #endif
  108.     }
  109.   return 0;
  110. }
  111.  
  112. #ifdef CAPITALIZE
  113. int 
  114. cap_ok (char *word, struct dent * dent)
  115. {
  116.   register char *dword;
  117.   register char *w;
  118.   int wcount;
  119.  
  120.   /*
  121.   ** All caps is always legal.
  122.   */
  123.   for (dword = word; *dword; dword++)
  124.     {
  125.       if (mylower (*dword))
  126.     break;
  127.     }
  128.   if (*dword == '\0')
  129.     return 1;            /* It was all caps */
  130.   if (dent->allcaps)
  131.     return 0;            /* Not all caps and required to be */
  132.   if (dent->followcase)
  133.     {
  134.       /*
  135.       ** It's a followcase word.  The correct capitalizations are
  136.       ** found following the main dent word.  When we find a
  137.       ** mismatch between letters, we assume we are in the suffix,
  138.       ** and begin insisting on the same case as the last letter
  139.       ** that matched.
  140.       */
  141.       dword = dent->word + strlen (dent->word) + 1;
  142.       wcount = *dword++ & 0xFF;
  143.       while (--wcount >= 0)
  144.     {
  145.       dword++;        /* Skip over keep flag */
  146.       for (w = word; *w; w++, dword++)
  147.         {
  148.           if (*dword != *w)
  149.         {
  150.           /* Begin suffix processing.  */
  151.           if (myupper (dword[-1]))
  152.             {
  153.               while (*w && !mylower (*w))
  154.             w++;
  155.               if (*w == '\0')
  156.             return 1;
  157.             }
  158.           else
  159.             {
  160.               while (*w && !myupper (*w))
  161.             w++;
  162.               if (*w == '\0')
  163.             return 1;
  164.             }
  165.           break;
  166.         }
  167.         }
  168.       if (*w == '\0')
  169.         return 1;
  170.       while (*dword++)    /* Skip to next prototype */
  171.         ;
  172.     }
  173.     }
  174.   /*
  175.   ** If it's a capitalize word, and the first letter is lowercase,
  176.   ** it's illegal.  Note that all-lowercase followcase words will
  177.   ** be found by the string scan above.
  178.   */
  179.   if (dent->capitalize && mylower (*word))
  180.     return 0;
  181.   /*
  182.   ** If it's not a followcase word, or if the capitalize flag is set,
  183.   ** capitalization (e.g. at the beginning of a sentence) is always
  184.   ** legal.  All-lowercase is also legal for non-followcase words.
  185.   */
  186.   if (!dent->followcase || dent->capitalize)
  187.     {
  188.       for (dword = word + 1; *dword; dword++)
  189.     {
  190.       if (myupper (*dword))
  191.         break;
  192.     }
  193.       if (*dword == '\0')
  194.     return 1;        /* It was all-lower or capitalized */
  195.     }
  196.   return 0;            /* Word has a bad mix of cases */
  197. }
  198.  
  199. #endif
  200.  
  201. void 
  202. flagpr (char *w, int flag, char *modpoint)
  203. {
  204.   register char *orig;
  205.  
  206.   /*
  207.   ** We refuse to print if the case at and after modpoint isn't
  208.   ** consistent with the case just before there.  This prevents
  209.   ** things like "OEM's" from being turned into OEM/M, which in
  210.   ** turn will only accept "OEM'S".
  211.   */
  212.   orig = orig_word + (modpoint - w);
  213.   if (myupper (orig[-1]))
  214.     {
  215.       while (*orig)
  216.     {
  217.       if (mylower (*orig++))
  218.         return;
  219.     }
  220.     }
  221.   else
  222.     {
  223.       while (*orig)
  224.     {
  225.       if (myupper (*orig++))
  226.         return;
  227.     }
  228.     }
  229.   /* Case is ok.  Now print it. */
  230.   for (orig = orig_word; *w && w < modpoint; orig++, w++)
  231.     putchar (*orig);
  232.   if (myupper (orig[-1]))
  233.     printf ("%s", w);
  234.   else
  235.     {
  236.       for (; *w; w++)
  237.     {
  238.       if (myupper (*w))
  239.         putchar (tolower (*w));
  240.       else
  241.         putchar (*w);
  242.     }
  243.     }
  244.   printf ("/%c\n", flag);
  245. }
  246.  
  247. void 
  248. g_ending (char *w, int n)
  249. {
  250.   register char *p;
  251.   register struct dent *dent;
  252.  
  253.   p = w + n - 3;        /* if the word ends in 'ing', then *p == 'i' */
  254.  
  255.   if (strcmp (p, "ING") != 0)
  256.     return;
  257.  
  258.   *p = 'E';            /* change I to E, like in CREATING */
  259.   *(p + 1) = 0;
  260.   n -= 2;
  261.  
  262.   if (n < 2)
  263.     return;
  264.  
  265.   if (cflag)
  266.     flagpr (w, 'G', p);
  267.   else if ((dent = lookup (w, n, 1)) != NULL
  268.        && dent->g_flag)
  269.     {
  270.       wordok = 1;
  271.       return;
  272.     }
  273.  
  274.  
  275.   *p = 0;
  276.   n--;
  277.  
  278.   if (n < 2)
  279.     return;
  280.  
  281.   if (p[-1] == 'E')
  282.     return;            /* this stops CREATEING */
  283.  
  284.   if (cflag)
  285.     flagpr (w, 'G', p);
  286.   else if ((dent = lookup (w, n, 1)) != NULL)
  287.     {
  288.       if (dent->g_flag)
  289.     wordok = 1;
  290.       return;
  291.     }
  292.   return;
  293. }
  294.  
  295. void 
  296. d_ending (char *w, int n)
  297. {
  298.   register char *p;
  299.   register struct dent *dent;
  300.  
  301.   p = w + n - 2;
  302.  
  303.   if (strcmp (p, "ED") != 0)
  304.     return;
  305.  
  306.   p[1] = 0;            /* kill 'D' */
  307.   n--;
  308.  
  309.   if (cflag)
  310.     flagpr (w, 'D', p + 1);
  311.   else if ((dent = lookup (w, n, 1)) != NULL)
  312.     {                /* eg CREATED */
  313.       if (dent->d_flag)
  314.     {
  315.       wordok = 1;
  316.       return;
  317.     }
  318.     }
  319.  
  320.   if (n < 3)
  321.     return;
  322.  
  323.   p[0] = 0;
  324.   n--;
  325.   p--;
  326.  
  327.   /* ED is now completely gone */
  328.  
  329.   if (p[0] == 'I' && !vowel (p[-1]))
  330.     {
  331.       p[0] = 'Y';
  332.       if (cflag)
  333.     flagpr (w, 'D', p);
  334.       else if ((dent = lookup (w, n, 1)) != NULL
  335.            && dent->d_flag)
  336.     {
  337.       wordok = 1;
  338.       return;
  339.     }
  340.       p[0] = 'I';
  341.     }
  342.  
  343.   if ((p[0] != 'E' && p[0] != 'Y') ||
  344.       (p[0] == 'Y' && vowel (p[-1])))
  345.     {
  346.       if (cflag)
  347.     flagpr (w, 'D', p + 1);
  348.       else if ((dent = lookup (w, n, 1)) != NULL)
  349.     {
  350.       if (dent->d_flag)
  351.         wordok = 1;
  352.       return;
  353.     }
  354.     }
  355. }
  356.  
  357. void 
  358. t_ending (char *w, int n)
  359. {
  360.  
  361.   register char *p;
  362.   register struct dent *dent;
  363.  
  364.   p = w + n - 3;
  365.  
  366.   if (strcmp (p, "EST") != 0)
  367.     return;
  368.  
  369.   p[1] = 0;            /* kill "ST" */
  370.   n -= 2;
  371.  
  372.   if (cflag)
  373.     flagpr (w, 'T', p);
  374.   else if ((dent = lookup (w, n, 1)) != NULL
  375.        && dent->t_flag)
  376.     {
  377.       wordok = 1;
  378.       return;
  379.     }
  380.  
  381.   if (n < 3)
  382.     return;
  383.  
  384.   p[0] = 0;            /* kill 'E' */
  385.   n--;
  386.   p--;
  387.  
  388.   /* EST is now completely gone */
  389.  
  390.   if (p[0] == 'I' && !vowel (p[-1]))
  391.     {
  392.       p[0] = 'Y';
  393.       if (cflag)
  394.     flagpr (w, 'T', p);
  395.       else if ((dent = lookup (w, n, 1)) != NULL
  396.            && dent->t_flag)
  397.     {
  398.       wordok = 1;
  399.       return;
  400.     }
  401.       p[0] = 'I';
  402.     }
  403.  
  404.   if ((p[0] != 'E' && p[0] != 'Y') ||
  405.       (p[0] == 'Y' && vowel (p[-1])))
  406.     {
  407.       if (cflag)
  408.     flagpr (w, 'T', p + 1);
  409.       else if ((dent = lookup (w, n, 1)) != NULL)
  410.     {
  411.       if (dent->t_flag)
  412.         wordok = 1;
  413.       return;
  414.     }
  415.     }
  416.  
  417. }
  418.  
  419.  
  420. void 
  421. r_ending (char *w, int n)
  422. {
  423.   register char *p;
  424.   register struct dent *dent;
  425.  
  426.   p = w + n - 2;
  427.  
  428.   if (strcmp (p, "ER") != 0)
  429.     return;
  430.  
  431.   p[1] = 0;            /* kill 'R' */
  432.   n--;
  433.  
  434.   if (cflag)
  435.     flagpr (w, 'R', p + 1);
  436.   else if ((dent = lookup (w, n, 1)) != NULL
  437.        && dent->r_flag)
  438.     {
  439.       wordok = 1;
  440.       return;
  441.     }
  442.  
  443.   if (n < 3)
  444.     return;
  445.  
  446.   p[0] = 0;            /* kill 'E' */
  447.   n--;
  448.   p--;
  449.  
  450.   /* ER is now completely gone */
  451.  
  452.   if (p[0] == 'I' && !vowel (p[-1]))
  453.     {
  454.       p[0] = 'Y';
  455.       if (cflag)
  456.     flagpr (w, 'R', p);
  457.       else if ((dent = lookup (w, n, 1)) != NULL
  458.            && dent->r_flag)
  459.     {
  460.       wordok = 1;
  461.       return;
  462.     }
  463.       p[0] = 'I';
  464.     }
  465.  
  466.   if ((p[0] != 'E' && p[0] != 'Y') ||
  467.       (p[0] == 'Y' && vowel (p[-1])))
  468.     {
  469.       if (cflag)
  470.     flagpr (w, 'R', p + 1);
  471.       else if ((dent = lookup (w, n, 1)) != NULL)
  472.     {
  473.       if (dent->r_flag)
  474.         wordok = 1;
  475.       return;
  476.     }
  477.     }
  478.  
  479. }
  480.  
  481. void 
  482. h_ending (char *w, int n)
  483. {
  484.   register char *p;
  485.   register struct dent *dent;
  486.  
  487.   p = w + n - 2;
  488.  
  489.   if (strcmp (p, "TH") != 0)
  490.     return;
  491.  
  492.   *p = 0;            /* kill "TH" */
  493.   n -= 2;
  494.  
  495.   p -= 2;
  496.  
  497.   if (p[1] != 'Y')
  498.     {
  499.       if (cflag)
  500.     flagpr (w, 'H', p + 2);
  501.       else if ((dent = lookup (w, n, 1)) != NULL
  502.            && dent->h_flag)
  503.     wordok = 1;
  504.     }
  505.  
  506.   if (strcmp (p, "IE") != 0)
  507.     return;
  508.  
  509.   p[0] = 'Y';            /* change "IE" to "Y" */
  510.   p[1] = 0;
  511.   n--;
  512.  
  513.   if (cflag)
  514.     flagpr (w, 'H', p + 1);
  515.   else if ((dent = lookup (w, n, 1)) != NULL)
  516.     if (dent->h_flag)
  517.       wordok = 1;
  518.  
  519. }
  520.  
  521. /*
  522.  * check for flags: X, J, Z, S, P, M
  523.  *
  524.  * X    -ions or -ications or -ens
  525.  * J    -ings
  526.  * Z    -ers or -iers
  527.  * S    -ies or -es or -s
  528.  * P    -iness or -ness
  529.  * M    -'S
  530.  */
  531.  
  532. void 
  533. s_ending (char *w, int n)
  534. {
  535.   register char *p;
  536.   register struct dent *dent;
  537.  
  538.   p = w + n;
  539.  
  540.   p[-1] = 0;            /* kill 'S' */
  541.   n--;
  542.  
  543.   if (strchr ("SXZHY", p[-2]) == NULL || (p[-2] == 'Y' && vowel (p[-3])))
  544.     {
  545.       if (cflag)
  546.     flagpr (w, 'S', p - 1);
  547.       else if ((dent = lookup (w, n, 1)) != NULL
  548.            && dent->s_flag)
  549.     {
  550.       wordok = 1;
  551.       return;
  552.     }
  553.     }
  554.  
  555.  
  556.   switch (p[-2])
  557.     {                /* letter before S */
  558.     case 'N':            /* X */
  559.       if (strcmp (p - 4, "ION") == 0)
  560.     {
  561.       p[-4] = 'E';        /* change "ION" to "E" */
  562.       p[-3] = 0;
  563.       n -= 2;
  564.       if (cflag)
  565.         flagpr (w, 'X', p - 4);
  566.       else if ((dent = lookup (w, n, 1)) != NULL
  567.            && dent->x_flag)
  568.         {
  569.           wordok = 1;
  570.           return;
  571.         }
  572.     }
  573.       if (strcmp (p - 8, "ICATE") == 0)
  574.     {
  575.       p[-8] = 'Y';        /* change "ICATE" to "Y" */
  576.       p[-7] = 0;
  577.       n -= 4;
  578.       if (cflag)
  579.         flagpr (w, 'X', p - 8);
  580.       else if ((dent = lookup (w, n, 1)) != NULL
  581.            && dent->x_flag)
  582.         wordok = 1;
  583.       return;
  584.     }
  585.       if (strcmp (p - 3, "EN") == 0 && p[-4] != 'E' && p[-4] != 'Y')
  586.     {
  587.       p[-3] = 0;        /* kill "EN" */
  588.       n -= 2;
  589.       if (cflag)
  590.         flagpr (w, 'X', p - 3);
  591.       else if ((dent = lookup (w, n, 1)) != NULL
  592.            && dent->x_flag)
  593.         wordok = 1;
  594.       return;
  595.     }
  596.       return;
  597.     case 'G':            /* J */
  598.       if (strcmp (p - 4, "ING") != 0)
  599.     return;
  600.       p[-4] = 'E';        /* change "ING" to "E" */
  601.       p[-3] = 0;
  602.       n -= 2;
  603.       if (cflag)
  604.     flagpr (w, 'J', p - 4);
  605.       else if ((dent = lookup (w, n, 1)) != NULL
  606.            && dent->j_flag)
  607.     {
  608.       wordok = 1;
  609.       return;
  610.     }
  611.       if (p[-5] == 'E')
  612.     return;            /* This stops CREATEING */
  613.       p[-4] = 0;        /* kill 'E' */
  614.       n--;
  615.       if (cflag)
  616.     flagpr (w, 'J', p - 4);
  617.       else if ((dent = lookup (w, n, 1)) != NULL
  618.            && dent->j_flag)
  619.     wordok = 1;
  620.       return;
  621.     case 'R':            /* Z */
  622.       if (strcmp (p - 3, "ER") != 0)
  623.     return;
  624.  
  625.       p[-2] = 0;        /* kill 'R' */
  626.       n--;
  627.       if (cflag)
  628.     flagpr (w, 'Z', p - 2);
  629.       else if ((dent = lookup (w, n, 1)) != NULL
  630.            && dent->z_flag)
  631.     {
  632.       wordok = 1;
  633.       return;
  634.     }
  635.       if (p[-4] == 'I' && !vowel (p[-5]))
  636.     {
  637.       p[-4] = 'Y';        /* change "IE" to "Y" */
  638.       p[-3] = 0;
  639.       n--;
  640.       if (cflag)
  641.         flagpr (w, 'Z', p - 4);
  642.       else if ((dent = lookup (w, n, 1)) != NULL
  643.            && dent->z_flag)
  644.         {
  645.           wordok = 1;
  646.           return;
  647.         }
  648.       p[-4] = 'I';        /* change 'Y' to 'I' */
  649.     }
  650.       if ((p[-4] != 'E' && p[-4] != 'Y') ||
  651.       (p[-4] == 'Y' && vowel (p[-5])))
  652.     {
  653.       if (p[-3])
  654.         n--;
  655.       p[-3] = 0;
  656.       if (cflag)
  657.         flagpr (w, 'Z', p - 3);
  658.       else if ((dent = lookup (w, n, 1)) != NULL
  659.            && dent->z_flag)
  660.         wordok = 1;
  661.     }
  662.       return;
  663.     case 'E':            /* S (except simple adding of an S) */
  664.       p[-2] = 0;        /* drop the E */
  665.       n--;
  666.       if (strchr ("SXZH", p[-3]) != NULL)
  667.     {
  668.       if (cflag)
  669.         flagpr (w, 'S', p - 2);
  670.       else if ((dent = lookup (w, n, 1)) != NULL)
  671.         {
  672.           if (dent->s_flag)
  673.         wordok = 1;;
  674.           return;
  675.         }
  676.     }
  677.       if (p[-3] == 'I' && !vowel (p[-4]))
  678.     {
  679.       p[-3] = 'Y';
  680.       if (cflag)
  681.         flagpr (w, 'S', p - 3);
  682.       else if ((dent = lookup (w, n, 1)) != NULL
  683.            && dent->s_flag)
  684.         wordok = 1;
  685.       return;
  686.     }
  687.       return;
  688.  
  689.     case 'S':            /* P */
  690.       if (strcmp (p - 4, "NES") != 0)
  691.     return;
  692.  
  693.       p[-4] = 0;        /* kill "NES" */
  694.       n -= 3;
  695.       if (p[-5] != 'Y' || vowel (p[-6]))
  696.     {
  697.       if (cflag)
  698.         flagpr (w, 'P', p - 4);
  699.       else if ((dent = lookup (w, n, 1)) != NULL
  700.            && dent->p_flag)
  701.         {
  702.           wordok = 1;
  703.           return;
  704.         }
  705.     }
  706.       if (p[-5] == 'I')
  707.     {
  708.       p[-5] = 'Y';
  709.       if (cflag)
  710.         flagpr (w, 'P', p - 5);
  711.       else if ((dent = lookup (w, n, 1)) != NULL
  712.            && dent->p_flag)
  713.         wordok = 1;
  714.     }
  715.       return;
  716.     case '\'':            /* M */
  717.       p[-2] = '\0';        /* kill "'" */
  718.       n--;
  719.       if (cflag)
  720.     flagpr (w, 'M', p - 2);
  721.       else if ((dent = lookup (w, n, 1)) != NULL
  722.            && dent->m_flag)
  723.     wordok = 1;
  724.       return;
  725.     }
  726. }
  727.  
  728. /* only the N flag */
  729. void 
  730. n_ending (char *w, int n)
  731. {
  732.   register char *p;
  733.   register struct dent *dent;
  734.  
  735.   p = w + n;
  736.  
  737.   if (p[-2] == 'E')
  738.     {
  739.       if (p[-3] == 'E' || p[-3] == 'Y')
  740.     return;
  741.       p[-2] = 0;        /* kill "EN" */
  742.       n -= 2;
  743.       if (cflag)
  744.     flagpr (w, 'N', p - 2);
  745.       else if ((dent = lookup (w, n, 1)) != NULL
  746.            && dent->n_flag)
  747.     wordok = 1;
  748.       return;
  749.     }
  750.  
  751.   if (strcmp (p - 3, "ION") != 0)
  752.     return;
  753.  
  754.   p[-3] = 'E';            /* change "ION" to "E" */
  755.   p[-2] = 0;
  756.   n -= 2;
  757.  
  758.   if (cflag)
  759.     flagpr (w, 'N', p - 3);
  760.   else if ((dent = lookup (w, n, 1)) != NULL)
  761.     {
  762.       if (dent->n_flag)
  763.     wordok = 1;
  764.       return;
  765.     }
  766.  
  767.   if (strcmp (p - 7, "ICATE") != 0)    /* check is really against "ICATION" */
  768.     return;
  769.  
  770.   p[-7] = 'Y';            /* change "ICATE" to "Y" */
  771.   p[-6] = 0;
  772.   n -= 4;
  773.  
  774.   if (cflag)
  775.     flagpr (w, 'N', p - 7);
  776.   else if ((dent = lookup (w, n, 1)) != NULL && dent->n_flag)
  777.     wordok = 1;
  778.   return;
  779. }
  780.  
  781. /* flags: v */
  782. void 
  783. e_ending (char *w, int n)
  784. {
  785.   register char *p;
  786.   register struct dent *dent;
  787.  
  788.   p = w + n;
  789.  
  790.   if (strcmp (p - 3, "IVE") != 0)
  791.     return;
  792.   p[-3] = 'E';            /* change "IVE" to "E" */
  793.   p[-2] = 0;
  794.   n -= 2;
  795.  
  796.   if (cflag)
  797.     flagpr (w, 'V', p - 3);
  798.   else if ((dent = lookup (w, n, 1)) != NULL
  799.        && dent->v_flag)
  800.     {
  801.       wordok = 1;
  802.       return;
  803.     }
  804.  
  805.   if (p[-4] == 'E')
  806.     return;
  807.  
  808.   p[-3] = 0;            /* kill 'E' */
  809.   n--;
  810.  
  811.   if (cflag)
  812.     flagpr (w, 'V', p - 3);
  813.   else if ((dent = lookup (w, n, 1)) != NULL && dent->v_flag)
  814.     wordok = 1;
  815.   return;
  816. }
  817.  
  818. /* flags: y */
  819. void 
  820. y_ending (char *w, int n)
  821. {
  822.   register char *p;
  823.   register struct dent *dent;
  824.  
  825.   p = w + n;
  826.  
  827.   if (strcmp (p - 2, "LY") != 0)
  828.     return;
  829.  
  830.   p[-2] = 0;            /* kill "LY" */
  831.   n -= 2;
  832.  
  833.   if (cflag)
  834.     flagpr (w, 'Y', p - 2);
  835.   else if ((dent = lookup (w, n, 1)) != NULL && dent->y_flag)
  836.     wordok = 1;
  837.   return;
  838. }
  839.  
  840. int 
  841. vowel (int c)
  842. {
  843.   return (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
  844. }
  845.