home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d191 / ispell.lha / ISpell / src.zoo / icombine.c < prev    next >
C/C++ Source or Header  |  1989-02-22  |  6KB  |  234 lines

  1. /* 
  2.    icombine:  combine multiple ispell dictionary entries into a single 
  3.               entry with the options of all entries
  4.  
  5.    Author:  Gary Puckering
  6.             Cognos, Inc.
  7.  
  8.    Written:  January 29, 1987
  9.    
  10.    Notes:  Input lines consist of a word followed optionally by
  11.            by one or more flags.  e.g CREATE/V/N/S
  12.            
  13.            Flags on lines with identical root words are combined.
  14.            No editing on flags is performed.
  15.            Flags are forced to uppercase, but roots are left alone.
  16.            Old-style flags, like /X/N will be output as /NX.
  17.            Flags are output in alphabetical order.
  18.            Non-letters appearing before the first "/" are retained,
  19.              those after are dropped.
  20.            Root words that differ only in capitalization are combined.
  21. */
  22.  
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #include "config.h"
  26. #include "ispell.h"
  27.  
  28. #define MAXFLAGS 26     /* letters A-Z */
  29. #define MAXLINE 255     /* maximum line size */
  30.  
  31. #define TRUE 1
  32. #define FALSE 0
  33. typedef int bool;
  34.  
  35. bool flagtbl[MAXFLAGS]; /* array of flag options */
  36.  
  37. char line[MAXLINE];     /* current line */
  38. char lastword[MAXLINE]; /* previous word */
  39. char uclastword[MAXLINE]; /* uppercase version of lastword */
  40. char word[MAXLINE];     /* current word */
  41. char ucword[MAXLINE];    /* uppercase version of current word */
  42. char flags[MAXLINE];    /* current flags */
  43. int  expand = 0;    /* if NZ, expand instead of combining */
  44.  
  45. extern char *strcpy ();
  46.  
  47.  
  48. main(argc,argv)
  49. int argc;
  50. char *argv[];
  51. {
  52.  
  53.     if (argc > 1  &&  strcmp (argv[1], "-e") == 0)
  54.     expand = 1;
  55.     if (gets(line)) 
  56.     {
  57.         parse(line,lastword,flags);
  58.         uccopy (uclastword, lastword);
  59.         getflags(flags);
  60.     }
  61.     else
  62.     return 0;
  63.  
  64.     while (gets(line))
  65.     {
  66.         parse(line,word,flags);
  67.         uccopy (ucword, word);
  68.         if (strcmp(word,lastword)!=0)   /* possibly different word */
  69.         {
  70.         if (strcmp (ucword, uclastword) != 0 /* truly different word */
  71.           ||  resolvecaps (word, ucword, lastword, uclastword))
  72.         {                    /* or caps differ */
  73.         putword();
  74.         strcpy(lastword,word);
  75.         strcpy(uclastword,ucword);
  76.         }
  77.         }
  78.         getflags(flags);
  79.     }
  80.     putword();
  81.     return 0;
  82. }
  83.  
  84. putword()
  85. {
  86.     printf("%s",lastword);
  87.     putflags();
  88. }
  89.  
  90. parse(ln,wrd,flgs)
  91.     char ln[];
  92.     char wrd[];
  93.     char flgs[];
  94. {
  95.     register char *p, *q;
  96.  
  97.     /* copy line up to first "/" or to end */
  98.     for (p=ln,q=wrd; *p && *p != '/'; p++,q++) *q = *p;
  99.     *q = NULL;
  100.  
  101.     strcpy(flgs,p);     /* copy from "/" to end */
  102. }
  103.  
  104. getflags(flgs)
  105.     char *flgs;
  106. {
  107.     register char *p;
  108.  
  109.     for (p=flgs; *p; p++) 
  110.         if (*p != '/')
  111.     {
  112.         if (islower (*p))
  113.         *p = toupper (*p);
  114.         if (isupper(*p))
  115.         flagtbl[(*p)-'A'] = TRUE;
  116.     }
  117. }
  118.  
  119. putflags()
  120. {
  121.     register int i;
  122.     int slashout = 0;
  123.  
  124.     if (expand)
  125.     putchar ('\n');
  126.  
  127.     for (i=0; i<MAXFLAGS; i++) 
  128.         if (flagtbl[i]) 
  129.         {
  130.         if (expand)
  131.         printf("%s/%c\n", lastword, i + 'A');
  132.             else
  133.         {
  134.         if (!slashout)
  135.             putchar('/');
  136.         slashout = 1;
  137.         putchar(i+'A');
  138.         }
  139.             flagtbl[i]=FALSE;
  140.         }
  141.     if (!expand)
  142.     putchar('\n');
  143. }
  144.  
  145. /*
  146.  * This routine resolves capitalization conflicts.  The idea is to combine
  147.  * only those cases that ispell can "uncombine".
  148.  *
  149.  * Entry: word and lastword differ, but only by case.
  150.  *
  151.  * Exit: Returns 1 if word and lastword both need to be in the dictionary,
  152.  *     0 if they can be handled by a single entry.  If the return is zero,
  153.  *     lastword may have been modified to reflect the union of the two
  154.  *     entries.
  155.  *
  156.  * Rules:
  157.  *
  158.  * (1) If either word is entirely in upper case, it "loses" to the other
  159.  *     word.  The "winning" word is copied to lastword, and 0 is returned.
  160.  * (2) If either word is "followcase" (defined as being mixed case with a
  161.  *     capital letter appearing after the first character), the two
  162.  *     variants are considered to differ, and 1 is returned.  Furthermore,
  163.  *     a flag is set (by copying the word to "lastfollow") so that all
  164.  *     future variants fo the word will be considered to differ.
  165.  * (3) If one word is capitalized and the other is all-lowercase, the
  166.  *     lowercase word "wins".  It is copied to lastword, and 0 is returned.
  167.  *     HOWEVER, if a "followcase" variant of the word has been seen, this
  168.  *     rule does not apply, and rule (4) will cause the words to be
  169.  *     considered different.
  170.  * (4) If a "followcase" variant of the word has been seen, the words are
  171.  *     always considered to differ.  1 is returned.
  172.  *
  173.  * Note that the input must be sorted with "sort -t/ +0f -1 +0 -1" for this
  174.  * code to work.
  175.  */
  176. resolvecaps (word, ucword, lastword, uclastword)
  177. char *word;
  178. char *ucword;
  179. char *lastword;
  180. char *uclastword;
  181. {
  182.     register char *w;
  183.     register char *lw;
  184.     static char lastfollow[200] = "";
  185.  
  186.     /* Rule (1): Upper case loses */
  187.     for (w = word;  *w  &&  !mylower (*w);  w++)
  188.     ;
  189.     if (*w == '\0')
  190.     return 0;
  191.     for (lw = lastword;  *lw  &&  !mylower (*lw);  lw++)
  192.     ;
  193.     if (*lw == '\0')
  194.     {
  195.     strcpy (lastword, word);
  196.     strcpy (uclastword, ucword);
  197.     return 0;
  198.     }
  199.     /* Rule (4):  followcase forces all subsequent variants to be different. */
  200.     if (strcmp (ucword, lastfollow) == 0)
  201.     return 1;
  202.     /* Rule (2):  "followcase" is different. */
  203.     for (w = word + 1, lw = lastword + 1;
  204.       *w  &&  !myupper (*w)  &&  !myupper (*lw);
  205.       w++, lw++)
  206.     ;
  207.     if (*w)        /* We don't test *lw 'cause lengths are the same */
  208.     {
  209.     strcpy (lastfollow, ucword);
  210.     return 1;
  211.     }
  212.     /* Rule (3):  all-lowercase beats capitalized */
  213.     if (myupper (lastword[0]))
  214.     {
  215.     strcpy (lastword, word);
  216.     strcpy (uclastword, ucword);
  217.     }
  218.     return 0;
  219. }
  220.  
  221. uccopy (dest, src)
  222. register char *dest;
  223. register char *src;
  224. {
  225.     while (*src)
  226.     {
  227.     if (mylower (*src))
  228.         *dest++ = toupper (*src++);
  229.     else
  230.         *dest++ = *src++;
  231.     }
  232.     *dest = '\0';
  233. }
  234.