home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 217_01 / spell.c < prev    next >
Text File  |  1979-12-31  |  7KB  |  296 lines

  1. /*
  2.   Program Name : spell.c
  3.   Author       : Kenji Hino
  4.   Descriptiton : It finds spelling errors and outputs error on the display.
  5.   Compiler     : Microsoft C compiler ver 4.0
  6.                  in small model, compact model, and huge model
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <ctype.h>
  11. #include <malloc.h>
  12.  
  13. #define MAX_DIR_ENTRIES  10000       /* The maximum number of keys  in index */
  14. #define MAXWORD          30         /* The maximum number of chars per word */
  15. #define MAXLINE          100        /* The maximum number of chars per line */
  16. #define DICTIONARY_FILE  "dict"
  17. #define DICTIONARY_INDEX "dictdx"
  18. #define DEFAULT_DIF      5         /* pick up a key every 10 words in dictionary */
  19. #define OK               1
  20. #define YES              1
  21. #define NO               -1
  22. #define ERROR            -1
  23.  
  24. FILE *dunit,                         /* file descriptor for dictionary file */
  25.      *dx;                            /* file descriptor for index file */
  26. int nlines = 0,                      /* number of index entries from index file */
  27.     freep = 0;                       /* next available index entry */
  28. struct free_list
  29.          {
  30.          char *key;                  /* address of key in main mem */
  31.          long addr;                  /* file pointer where a word is stored */
  32.          } index[MAX_DIR_ENTRIES];
  33.  
  34. main(argc, argv)
  35. int argc;
  36. char **argv;
  37. {
  38. FILE *unit;
  39. void lodidx(),cant(),dospel();
  40.  
  41. lodidx();                             /* load dictionary index */
  42. while ( argc-- != 1 )
  43.   {
  44.   argv++;
  45.   if ((unit = fopen(*argv,"r")) == NULL)
  46.     cant(*argv);
  47.   else
  48.     {
  49.     dospel(unit);                     /* do spell checking */
  50.     fclose(unit);
  51.     }
  52.   }
  53. } /* end of main */
  54.  
  55. void lodidx()
  56. {
  57. void errormes(),cant(),dodx();
  58. int inject();
  59. long addr;
  60. char key[MAXWORD];
  61.  
  62. if ((dunit = fopen(DICTIONARY_FILE, "r")) == NULL)
  63.   cant(DICTIONARY_FILE);
  64.  
  65. if ((dx = fopen(DICTIONARY_INDEX, "r")) == NULL)
  66.   dodx(DICTIONARY_INDEX);                       /* create index file */
  67. else
  68.   while ( fscanf(dx,"%s%lx",key,&addr) != EOF )
  69.     {
  70.     if (inject(key,addr) == ERROR)              /* create index in main mem */
  71.       {
  72.       errormes("dictinary index too long or run out of memory !!");
  73.       break;
  74.       }
  75.     };
  76. fclose(dx);
  77. } /* end of lodidx */
  78.  
  79. int inject(key,addr)      /* injext a key into mian mem */
  80. char *key;
  81. long addr;
  82. {
  83. char *str,*malloc();
  84.  
  85. if ((freep >= MAX_DIR_ENTRIES) || ((str = malloc(strlen(key) + 1)) == NULL))
  86.   return(ERROR);
  87.  
  88. strcpy(str,key);
  89. index[freep].key = str;
  90. index[freep].addr = addr;
  91. freep++;
  92. nlines++;
  93. return(OK);
  94. } /* end of inject */
  95.  
  96. void dodx(name)     /* create index file */
  97. char *name;
  98. {
  99. void cant(),errormes(), outlin();
  100. int doline(), inject();
  101. char key[MAXWORD];
  102. long addr = 0;
  103. long n = 0;
  104.  
  105. if ((dx = fopen(name,"w")) == NULL)
  106.   cant(name);
  107.  
  108. addr = ftell(dunit);
  109. while (fscanf(dunit, "%s",key) != EOF)
  110.   {
  111.   n++;
  112.   if (doline(n,DEFAULT_DIF) == YES)
  113.     {
  114.     outlin(key,addr,dx);
  115.     if (inject(key,addr) == ERROR)
  116.       errormes("dictionary index too large or run out of memeory !!");
  117.     }
  118.   addr = ftell(dunit);
  119.   }
  120. } /* end of dodx */
  121.  
  122. int doline(n,dif)        /* decide whether pick  up a key or not */
  123. long n;
  124. int dif;
  125. {
  126.  
  127. if (dif == 1)
  128.   return(YES);
  129. else if ((n%dif) == 1)
  130.        return(YES);
  131.      else
  132.        return(NO);
  133. } /* end of doline */
  134.  
  135. void outlin(word, addr,out)    /* write index into a index file */
  136. char *word;
  137. long addr;
  138. FILE *out;
  139. {
  140. fprintf(out,"%s %lx\n",word,addr);
  141. } /* end of outlin */
  142.  
  143. void dospel(unit)             /* do spell checking */
  144. FILE *unit;
  145. {
  146. char errbuf[MAXLINE];       /* to show error on stdout */
  147. char word[MAXWORD];
  148. char buf[MAXLINE];
  149. int  gtword(), findwd();
  150. int i,j,start,iferr;
  151.  
  152. while (fgets(buf,MAXLINE,unit) != NULL)       /* get a line from a target file */
  153.   {
  154.   fprintf(stdout,"%s",buf);
  155.   for(j=0; buf[j] != '\0'; j++)              /* set up error buf */
  156.     if (buf[j] == '\t')
  157.       errbuf[j] = '\t';
  158.     else if (buf[j] == '\n')
  159.            errbuf[j] = '\n';
  160.          else errbuf[j] =' ';
  161.   errbuf[j] = '\0';
  162.  
  163.   iferr = NO;
  164.   start = i = 0;
  165.   while (gtword(buf, &i, word, &start) > 0)     /* get a word */
  166.     if (findwd(word) == NO)                     /* search the word */
  167.       {
  168.       iferr = YES;
  169.       for(j=start; j < i; j++)               /* make errbuf */
  170.         errbuf[j] = '*';
  171.       };
  172.   if (iferr == YES)
  173.     fprintf(stdout,"%s",errbuf);
  174.   } /* while end */
  175. } /* end of dospel */
  176.  
  177. int gtword(buf,i,word,start)     /* get a word from a line */
  178. char *buf,*word;
  179. int *i,*start;
  180. {
  181. int j,alphan();
  182.  
  183. while (alphan(buf[*i]) == NO)             /* skip non-alphan */
  184.   if (buf[*i] == '\0')
  185.     return(0);
  186.   else
  187.     (*i)++;
  188. *start = *i;
  189. for(j=0; alphan(buf[*i]) == YES; j++)    /* get a word */
  190.   {
  191.   word[j] = buf[*i];
  192.   (*i)++;
  193.   }
  194. word[j] = '\0';
  195. return(strlen(word));
  196. } /* end of gtword */
  197.  
  198. int alphan(ch)
  199. char ch;
  200. {
  201. int c;
  202.  
  203. c = ch;
  204. if ((isalpha(c) != 0) || (isdigit(c) != 0))
  205.   return(YES);
  206. else
  207.   return(NO);
  208. } /* end of alphan */
  209.  
  210. int findwd(word)
  211. char *word;
  212. {
  213. int i,cmp;
  214. void wdstal();
  215. int wdlook(),binsrc();
  216. char buf[MAXLINE];
  217.  
  218. if (wdlook(word) == YES)      /* seen this mis-spelled word before */
  219.   return(NO);
  220. i = binsrc(word);             /* do binary search */
  221. fseek(dunit,index[i].addr,SEEK_SET); /* move file pointer in dictionary file */
  222. while (fscanf(dunit, "%s",buf) != EOF)
  223.   if ((cmp =strcmpi(word,buf)) == 0)  /* strcmpi is case-insensitive */
  224.     return(YES);
  225.   else if (cmp < 0)
  226.          {
  227.          wdstal(word);        /* install mis-spelled word */
  228.          return(NO);
  229.          };
  230. wdstal(word);
  231. return(NO);
  232. } /* end of fdword */
  233.  
  234. int binsrc(word)       /* do binary search */
  235. char *word;
  236. {
  237. int i,last,first,cmp;
  238.  
  239. if (strcmpi(word,index[nlines-1].key) > 0)   /* if a word is greater than the greatest word in index */
  240.   return(nlines-1);
  241. if (strcmpi(word,index[0].key) < 0)       /* if a word is less than smallest word */
  242.   return(0);
  243. first = 0;
  244. last = nlines;
  245. while ((last - first) > 1)
  246.   {
  247.   i = (first+last)/2;
  248.   if ((cmp = strcmpi(word,index[i].key)) < 0)
  249.     last = i;
  250.   else if (cmp == 0)
  251.          {
  252.          last = i;
  253.          first = i;
  254.          }
  255.        else if (cmp > 0)
  256.               first =i;
  257.   } /* while end */
  258. return(first);
  259. } /* end of bisrc */
  260.  
  261. int wdlook(word)
  262. char *word;
  263. {
  264. int i;
  265.  
  266. for(i=nlines; i < freep; i++)
  267.   if (strcmpi(word,index[i].key) == 0)
  268.     return(YES);
  269. return(NO);
  270. } /* end of wdlook */
  271.  
  272. void wdstal(word)
  273. char *word;
  274. {
  275. char *str;
  276.  
  277. if ((freep <= MAX_DIR_ENTRIES) && ((str = malloc(strlen(word) + 1)) != NULL))
  278.   {
  279.   strcpy(str,word);
  280.   index[freep++].key = str;
  281.   }
  282. } /* end of wdstal */
  283.  
  284. void cant(name)
  285. char *name;
  286. {
  287. fprintf(stderr,"Can't open %s!\n",name);
  288. exit(1);
  289. }
  290.  
  291. void errormes(message)
  292. char *message;
  293. {
  294. fprintf(stdout,"%s\n",message);
  295. }
  296.