home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / gnu / ispell-4.0-src.lha / ispell-4.0 / screen.c < prev    next >
C/C++ Source or Header  |  1994-02-24  |  19KB  |  956 lines

  1. /* Copyright (C) 1990, 1993 Free Software Foundation, Inc.
  2.  
  3.    This file is part of GNU ISPELL.
  4.  
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.  
  10.    This program is distributed in the hope that it will be useful,
  11.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.    GNU General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License
  16.    along with this program; if not, write to the Free Software
  17.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19.  
  20. #include <stdio.h>
  21. #include <ctype.h>
  22. #include <setjmp.h>
  23. #include <signal.h>
  24. #include "ispell.h"
  25. #include "hash.h"
  26.  
  27. int reading_interactive_command;
  28. jmp_buf command_loop;
  29.  
  30. extern struct sp_corrections corrections;
  31.  
  32. #ifdef __STDC__
  33. static void copyout (char **, int, FILE *);
  34. #else
  35. static void copyout ();
  36. #endif
  37.  
  38. extern int lflag;
  39. extern int uflag;
  40. extern int iflag;
  41. extern FILE *sortf;
  42. extern int Sflag;
  43. extern int intr_typed;
  44.  
  45. char tempfile[100];
  46.  
  47. #define NOPARITY 0x7f
  48.  
  49. static void
  50. giveihelp ()
  51. {
  52.   erase ();
  53.   printf ("You have interrupted ISPELL.  Commands are:\r\n");
  54.   printf ("\r\n");
  55.   printf ("SPACE    Continue scanning the current file.\r\n");
  56.   printf ("Q        Write changes so far, and ignore misspellings in\r\n");
  57.   printf ("             the rest of the file.\r\n");
  58.   printf ("X        Abandon changes to this file.\r\n");
  59.   printf ("!       Shell escape.\r\n");
  60.   printf ("^L      Redraw screen.\r\n");
  61.   printf ("\r\n\r\n");
  62.   printf ("-- Type space to continue --");
  63.   fflush (stdout);
  64.   getchar ();
  65. }
  66.  
  67. static void
  68. givehelp ()
  69. {
  70.   erase ();
  71.   (void) printf ("Whenever a word is found that is not in the dictionary,\r\n");
  72.   (void) printf ("it is printed on the first line of the screen.  If the dictionary\r\n");
  73.   (void) printf ("contains any similar words, they are listed with a single digit\r\n");
  74.   (void) printf ("next to each one.  You have the option of replacing the word\r\n");
  75.   (void) printf ("completely, or choosing one of the suggested words.\r\n");
  76.   (void) printf ("\r\n");
  77.   (void) printf ("Commands are:\r\n\r\n");
  78.   (void) printf ("R       Replace the misspelled word completely.\r\n");
  79.   (void) printf ("Space   Accept the word this time only\r\n");
  80.   (void) printf ("A       Accept the word for the rest of this file.\r\n");
  81.   (void) printf ("I       Accept the word, and put it in your private dictionary.\r\n");
  82.   (void) printf ("0-9     Replace with one of the suggested words.\r\n");
  83.   (void) printf ("<NL>    Recompute near misses.  Use this if you interrupted\r\n");
  84.   (void) printf ("             the near miss generator, and you want it to\r\n");
  85.   (void) printf ("             again on this word.\r\n");
  86.   (void) printf ("Q       Write the rest of this file, ignoring misspellings,\r\n");
  87.   (void) printf ("            and start next file.\r\n");
  88.   (void) printf ("X       Exit immediately.  Asks for conformation.\r\n");
  89.   (void) printf ("            Leaves file unchanged.\r\n");
  90.   (void) printf ("!       Shell escape.\r\n");
  91.   (void) printf ("^L      Redraw screen.\r\n");
  92.   (void) printf ("\r\n\r\n");
  93.   (void) printf ("-- Type space to continue --");
  94.   (void) fflush (stdout);
  95.   (void) getchar ();
  96. }
  97.  
  98.  
  99. char *getline ();
  100.  
  101. char firstbuf[BUFSIZ], secondbuf[BUFSIZ];
  102. char gtoken[BUFSIZ + 10];
  103.  
  104. int quit;
  105.  
  106. char *currentfile = NULL;
  107. static long filesize;
  108. static FILE *filestream;
  109.  
  110. int changed;
  111.  
  112. void
  113. dofile (filename)
  114.   char *filename;
  115. {
  116.   int c;
  117.   FILE *in, *out;
  118.   void (*oldf) (NOARGS);
  119.  
  120.   currentfile = filename;
  121.  
  122.   if ((in = fopen (filename, "r")) == NULL)
  123.     {
  124.       (void) fprintf (stderr, "Can't open %s\r\n", filename);
  125.       return;
  126.     }
  127.  
  128.   changed = 0;
  129.  
  130.   filesize = lseek (fileno (in), 0l, 2);
  131.   (void) lseek (fileno (in), 0l, 0);
  132.  
  133.   if (access (filename, 2) < 0)
  134.     {
  135.       (void) fprintf (stderr, "Can't write to %s\r\n", filename);
  136.       return;
  137.     }
  138.  
  139.   (void) strcpy (tempfile, "/tmp/ispellXXXXXX");
  140.   (void) mktemp (tempfile);
  141.   if ((out = fopen (tempfile, "w")) == NULL)
  142.     {
  143.       (void) fprintf (stderr, "Can't create %s\r\n", tempfile);
  144.       return;
  145.     }
  146.  
  147.   quit = 0;
  148.  
  149.   checkfile (in, out, (long) 0);
  150.  
  151.   (void) fclose (in);
  152.   (void) fclose (out);
  153.  
  154.   if (changed == 0)
  155.     {
  156.       (void) unlink (tempfile);
  157.       tempfile[0] = 0;
  158.       return;
  159.     }
  160.  
  161.   if ((in = fopen (tempfile, "r")) == NULL)
  162.     {
  163.       (void) fprintf (stderr, "tempoary file disappeared (%s)\r\n", tempfile);
  164.       (void) sleep (2);
  165.       return;
  166.     }
  167.  
  168.   oldf = (void (*)(NOARGS)) signal (SIGINT, SIG_IGN);
  169.  
  170.   if ((out = fopen (filename, "w")) == NULL)
  171.     {
  172.       (void) unlink (tempfile);
  173.       tempfile[0] = 0;
  174.       (void) fprintf (stderr, "can't create %s\r\n", filename);
  175.       (void) sleep (2);
  176.       return;
  177.     }
  178.  
  179.   while ((c = getc (in)) != EOF)
  180.     putc (c, out);
  181.  
  182.   fclose (in);
  183.   (void) fclose (out);
  184.  
  185.   (void) unlink (tempfile);
  186.   tempfile[0] = 0;
  187.  
  188.   signal (SIGINT, (RETSIGTYPE (*)()) oldf);
  189. }
  190.  
  191. char *currentchar;
  192. FILE *out;
  193.  
  194.  
  195. void
  196. checkfile (in, outx, end)
  197.      FILE *in, *outx;
  198.      long end;
  199. {
  200.   char *p;
  201.   int maybe_troff;
  202.   char *cstart, *cend;
  203.   int i;
  204.   long lineoffset;
  205.  
  206.   out = outx;
  207.  
  208. checkstart:
  209.   filestream = in;
  210.   secondbuf[0] = 0;
  211.  
  212.   maybe_troff = 0;
  213.   while (1)
  214.     {
  215.       (void) strcpy (firstbuf, secondbuf);
  216.       if (quit)
  217.     {
  218.       if (out == NULL)
  219.         return;
  220.       while (fgets (secondbuf, sizeof secondbuf, in)
  221.          != NULL)
  222.         (void) fputs (secondbuf, out);
  223.       break;
  224.     }
  225.  
  226.       if (Sflag)
  227.     {
  228.       lineoffset = ftell (in);
  229.       if (end && lineoffset >= end)
  230.         break;
  231.     }
  232.       if (fgets (secondbuf, sizeof secondbuf, in) == NULL)
  233.     break;
  234.  
  235.       /* uflag is on when emulating traditional spell
  236.          * if so, then follow troff commands '.so' and '.nx'
  237.          */
  238.       if (uflag && !iflag && secondbuf[0] == '.')
  239.     {
  240.       int soflag = 0, nxflag = 0;
  241.       FILE *so;
  242.       char *n, *end;
  243.       if (strncmp (secondbuf, ".so", 3) == 0)
  244.         soflag = 1;
  245.       if (strncmp (secondbuf, ".nx", 3) == 0)
  246.         nxflag = 1;
  247.       if (soflag || nxflag)
  248.         {
  249.           n = secondbuf + 3;
  250.           while (isspace (*n))
  251.         n++;
  252.           end = n;
  253.           while (*end && !isspace (*end))
  254.         end++;
  255.           *end = 0;
  256.           if (strncmp (n, "/gnu/lib", 8) == 0)
  257.         continue;
  258.           if (nxflag)
  259.         {
  260.           if (freopen (n, "r", in) == NULL)
  261.             {
  262.               (void) fprintf (stderr, "can't open %s\n",
  263.                       n);
  264.               return;
  265.             }
  266.           goto checkstart;
  267.         }
  268.           if ((so = fopen (n, "r")) == NULL)
  269.         {
  270.           (void) fprintf (stderr,
  271.                   "can't open %s\n", n);
  272.         }
  273.           else
  274.         {
  275.           /* FIXME: gcc -Wall found the third argument missing in this call
  276.            to checkfile. The function isn't documented, so I have no idea what
  277.            it actually is supposed flag. My assumption is that it worked in most
  278.            instances because random junk on the stack would likely be non-zero.
  279.            --bson */
  280.  
  281.           checkfile (so, (FILE *) NULL, (long) 1);
  282.           (void) fclose (so);
  283.         }
  284.           continue;
  285.         }
  286.     }
  287.  
  288.       currentchar = secondbuf;
  289.  
  290.       p = secondbuf + strlen (secondbuf) - 1;
  291.       if (*p == '\n')
  292.     *p = 0;
  293.  
  294.       while (1)
  295.     {
  296.       if (skip_to_next_word (out) == 0)
  297.         break;
  298.       cstart = currentchar;
  299.       cend = cstart;
  300.       if (intr_typed)
  301.         {
  302.           if (lflag || Sflag)
  303.         return;
  304.  
  305.           gtoken[0] = 0;
  306.           (void) correct (gtoken, sizeof gtoken,
  307.                   cstart, cend, ¤tchar);
  308.           if (quit)
  309.         {
  310.           (void) fputs (currentchar, out);
  311.           break;
  312.         }
  313.           intr_typed = 0;
  314.         }
  315.  
  316.       /* first letter is a lexletter, therefore,
  317.              * loop will execute at least once
  318.              */
  319.       p = gtoken;
  320.       i = 0;
  321.       while (islexletter (*cend) && i < MAX_WORD_LEN - 5)
  322.         {
  323.           *p++ = *cend++;
  324.           i++;
  325.         }
  326.       /* flush quote if at end of word */
  327.       if (p[-1] == '\'')
  328.         {
  329.           p--;
  330.           cend--;
  331.         }
  332.       *p = 0;
  333.  
  334.       currentchar = cend;
  335.  
  336.       if (good (gtoken, strlen (gtoken), 0))
  337.         {
  338.           if (out)
  339.         (void) fputs (gtoken, out);
  340.           continue;
  341.         }
  342.       interaction_flag = 1;
  343.       /* word is bad */
  344.       if (uflag)
  345.         {
  346.           /* traditional spell compatability */
  347.           (v