This is ispell.c in view mode; [Download] [Up]
#ifndef lint static char Rcs_Id[] = "$Id: ispell.c,v 1.123 1994/05/17 06:44:12 geoff Exp $"; #endif #define MAIN /* * ispell.c - An interactive spelling corrector. * * Copyright (c), 1983, by Pace Willisson * * Copyright 1992, 1993, Geoff Kuenning, Granada Hills, CA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All modifications to the source code must be clearly marked as * such. Binary redistributions based on modified source code * must be clearly marked as modified versions in the documentation * and/or other materials provided with the distribution. * 4. All advertising materials mentioning features or use of this software * must display the following acknowledgment: * This product includes software developed by Geoff Kuenning and * other unpaid contributors. * 5. The name of Geoff Kuenning may not be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY GEOFF KUENNING AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL GEOFF KUENNING OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * $Log: ispell.c,v $ * Revision 1.123 1994/05/17 06:44:12 geoff * Add support for controlled compound formation and the COMPOUNDONLY * option to affix flags. * * Revision 1.122 1994/04/27 01:50:37 geoff * Print MAX_CAPS in -vv mode. * * Revision 1.121 1994/03/16 03:49:10 geoff * Fix -vv to display the value of NO_STDLIB_H. * * Revision 1.120 1994/03/15 06:24:28 geoff * Allow the -t, -n, and -T switches to override each other, as follows: * if no switches are given, the deformatter and string characters are * chosen based on the file suffix. If only -t/-n are given, the * deformatter is forced but string cahracters come from the file suffix. * If only -T is given, the deformatter is chosen based on the value * given in the -T switch. Finally, if both -T and -t/-n are given, * string characters are controlled by -T and the deformatter by -t/-n. * * Revision 1.119 1994/03/15 05:58:07 geoff * Get rid of a gcc warning * * Revision 1.118 1994/03/15 05:30:37 geoff * Get rid of an unused-variable complaint by proper ifdeffing * * Revision 1.117 1994/03/12 21:26:48 geoff * Correctly limit maximum name lengths for files that have directory paths * included. Also don't use a wired-in 256 for the size of the backup file * name. * * Revision 1.116 1994/02/07 08:10:44 geoff * Print GENERATE_LIBRARY_PROTOS in the -vv switch. * * Revision 1.115 1994/01/26 07:44:47 geoff * Make yacc configurable through local.h. * * Revision 1.114 1994/01/25 07:11:44 geoff * Get rid of all old RCS log lines in preparation for the 3.1 release. * */ #include "config.h" #include "ispell.h" #include "proto.h" #include "msgs.h" #include "version.h" #include <ctype.h> #include <sys/stat.h> static void usage P ((void)); static void initckch P ((char * wchars)); int main P ((int argc, char * argv[])); static void dofile P ((char * filename)); static void update_file P ((char * filename, struct stat * statbuf)); static void expandmode P ((int printorig)); static char * Cmd; static char * LibDict = NULL; /* Pointer to name of $(LIBDIR)/dict */ static void usage () { (void) fprintf (stderr, ISPELL_C_USAGE1, Cmd); (void) fprintf (stderr, ISPELL_C_USAGE2, Cmd); (void) fprintf (stderr, ISPELL_C_USAGE3, Cmd); (void) fprintf (stderr, ISPELL_C_USAGE4, Cmd); (void) fprintf (stderr, ISPELL_C_USAGE5, Cmd); (void) fprintf (stderr, ISPELL_C_USAGE6, Cmd); (void) fprintf (stderr, ISPELL_C_USAGE7, Cmd); givehelp (0); exit (1); } static void initckch (wchars) char * wchars; /* Characters in -w option, if any */ { register ichar_t c; char num[4]; for (c = 0; c < (ichar_t) (SET_SIZE + hashheader.nstrchars); ++c) { if (iswordch (c)) { if (!mylower (c)) { Try[Trynum] = c; ++Trynum; } } } if (wchars != NULL) { while (Trynum < SET_SIZE && *wchars != '\0') { if (*wchars != 'n' && *wchars != '\\') { c = *wchars; ++wchars; } else { ++wchars; num[0] = '\0'; num[1] = '\0'; num[2] = '\0'; num[3] = '\0'; if (isdigit (wchars[0])) { num[0] = wchars[0]; if (isdigit (wchars[1])) { num[1] = wchars[1]; if (isdigit (wchars[2])) num[2] = wchars[2]; } } if (wchars[-1] == 'n') { wchars += strlen (num); c = atoi (num); } else { wchars += strlen (num); c = 0; if (num[0]) c = num[0] - '0'; if (num[1]) { c <<= 3; c += num[1] - '0'; } if (num[2]) { c <<= 3; c += num[2] - '0'; } } } c &= NOPARITY; if (!hashheader.wordchars[c]) { hashheader.wordchars[c] = 1; hashheader.sortorder[c] = hashheader.sortval++; Try[Trynum] = c; ++Trynum; } } } } int main (argc, argv) int argc; char * argv[]; { char * p; char * cpd; char ** versionp; char * wchars = NULL; char * preftype = NULL; static char libdictname[sizeof DEFHASH]; static char outbuf[BUFSIZ]; int argno; int arglen; Cmd = *argv; Trynum = 0; (void) sprintf (hashname, "%s/%s", LIBDIR, DEFHASH); cpd = NULL; argv++; argc--; while (argc && **argv == '-') { /* * Trying to add a new flag? Can't remember what's been used? * Here's a handy guide: * * Used: * * ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 * ^^^^ ^^^ ^ ^^ ^^ * abcdefghijklmnopqrstuvwxyz * ^^^^^^ ^^^ ^ ^^ ^^^ */ arglen = strlen (*argv); switch ((*argv)[1]) { case 'v': if (arglen > 3) usage (); for (versionp = Version_ID; *versionp; ) { p = *versionp++; if (strncmp (p, "(#) ", 5) == 0) p += 5; (void) printf ("%s\n", p); } if ((*argv)[2] == 'v') { (void) printf (ISPELL_C_OPTIONS_ARE); #ifdef USG (void) printf ("\tUSG\n"); #else /* USG */ (void) printf ("\t!USG (BSD)\n"); #endif /* USG */ (void) printf ("\tBAKEXT = \"%s\"\n", BAKEXT); (void) printf ("\tBINDIR = \"%s\"\n", BINDIR); #ifdef BOTTOMCONTEXT (void) printf ("\tBOTTOMCONTEXT\n"); #else /* BOTTOMCONTEXT */ (void) printf ("\t!BOTTOMCONTEXT\n"); #endif /* BOTTOMCONTEXT */ #if TERM_MODE == CBREAK (void) printf ("\tCBREAK\n"); #endif /* TERM_MODE */ (void) printf ("\tCC = \"%s\"\n", CC); (void) printf ("\tCFLAGS = \"%s\"\n", CFLAGS); #ifdef COMMANDFORSPACE (void) printf ("\tCOMMANDFORSPACE\n"); #else /* COMMANDFORSPACE */ (void) printf ("\t!COMMANDFORSPACE\n"); #endif /* COMMANDFORSPACE */ #ifdef CONTEXTROUNDUP (void) printf ("\tCONTEXTROUNDUP\n"); #else /* CONTEXTROUNDUP */ (void) printf ("\t!CONTEXTROUNDUP\n"); #endif /* CONTEXTROUNDUP */ (void) printf ("\tCONTEXTPCT = %d\n", CONTEXTPCT); (void) printf ("\tDEFHASH = \"%s\"\n", DEFHASH); (void) printf ("\tDEFINCSTR = \"%s\"\n", DEFINCSTR); (void) printf ("\tDEFLANG = \"%s\"\n", DEFLANG); (void) printf ("\tDEFNOBACKUPFLAG = %d\n", DEFNOBACKUPFLAG); (void) printf ("\tDEFPAFF = \"%s\"\n", DEFPAFF); (void) printf ("\tDEFPDICT = \"%s\"\n", DEFPDICT); (void) printf ("\tDEFTEXFLAG = %d\n", DEFTEXFLAG); (void) printf ("\tEGREPCMD = \"%s\"\n", EGREPCMD); (void) printf ("\tELISPDIR = \"%s\"\n", ELISPDIR); (void) printf ("\tEMACS = \"%s\"\n", EMACS); #ifdef EQUAL_COLUMNS (void) printf ("\tEQUAL_COLUMNS\n"); #else /* EQUAL_COLUMNS */ (void) printf ("\t!EQUAL_COLUMNS\n"); #endif /* EQUAL_COLUMNS */ #ifdef GENERATE_LIBRARY_PROTOS (void) printf ("\tGENERATE_LIBRARY_PROTOS\n"); #else /* GENERATE_LIBRARY_PROTOS */ (void) printf ("\t!GENERATE_LIBRARY_PROTOS\n"); #endif /* GENERATE_LIBRARY_PROTOS */ #ifdef IGNOREBIB (void) printf ("\tIGNOREBIB\n"); #else /* IGNOREBIB */ (void) printf ("\t!IGNOREBIB\n"); #endif /* IGNOREBIB */ (void) printf ("\tINCSTRVAR = \"%s\"\n", INCSTRVAR); (void) printf ("\tINPUTWORDLEN = %d\n", INPUTWORDLEN); (void) printf ("\tLANGUAGES = \"%s\"\n", LANGUAGES); (void) printf ("\tLIBDIR = \"%s\"\n", LIBDIR); (void) printf ("\tLIBES = \"%s\"\n", LIBES); (void) printf ("\tLINT = \"%s\"\n", LINT); (void) printf ("\tLINTFLAGS = \"%s\"\n", LINTFLAGS); #ifndef REGEX_LOOKUP (void) printf ("\tLOOK = \"%s\"\n", LOOK); #endif /* REGEX_LOOKUP */ (void) printf ("\tMAKE_SORTTMP = \"%s\"\n", MAKE_SORTTMP); (void) printf ("\tMALLOC_INCREMENT = %d\n", MALLOC_INCREMENT); (void) printf ("\tMAN1DIR = \"%s\"\n", MAN1DIR); (void) printf ("\tMAN1EXT = \"%s\"\n", MAN1EXT); (void) printf ("\tMAN4DIR = \"%s\"\n", MAN4DIR); (void) printf ("\tMAN4EXT = \"%s\"\n", MAN4EXT); (void) printf ("\tMASKBITS = %d\n", MASKBITS); (void) printf ("\tMASKTYPE = %s\n", MASKTYPE_STRING); (void) printf ("\tMASKTYPE_WIDTH = %d\n", MASKTYPE_WIDTH); (void) printf ("\tMASTERHASH = \"%s\"\n", MASTERHASH); (void) printf ("\tMAXAFFIXLEN = %d\n", MAXAFFIXLEN); (void) printf ("\tMAXCONTEXT = %d\n", MAXCONTEXT); (void) printf ("\tMAXINCLUDEFILES = %d\n", MAXINCLUDEFILES); (void) printf ("\tMAXNAMLEN = %d\n", MAXNAMLEN); (void) printf ("\tMAXPATHLEN = %d\n", MAXPATHLEN); (void) printf ("\tMAXPCT = %d\n", MAXPCT); (void) printf ("\tMAXSEARCH = %d\n", MAXSEARCH); (void) printf ("\tMAXSTRINGCHARLEN = %d\n", MAXSTRINGCHARLEN); (void) printf ("\tMAXSTRINGCHARS = %d\n", MAXSTRINGCHARS); (void) printf ("\tMAX_CAPS = %d\n", MAX_CAPS); (void) printf ("\tMAX_HITS = %d\n", MAX_HITS); (void) printf ("\tMAX_SCREEN_SIZE = %d\n", MAX_SCREEN_SIZE); (void) printf ("\tMINCONTEXT = %d\n", MINCONTEXT); #ifdef MINIMENU (void) printf ("\tMINIMENU\n"); #else /* MINIMENU */ (void) printf ("\t!MINIMENU\n"); #endif /* MINIMENU */ (void) printf ("\tMINWORD = %d\n", MINWORD); (void) printf ("\tMSGLANG = %s\n", MSGLANG); #ifdef NO_CAPITALIZATION_SUPPORT (void) printf ("\tNO_CAPITALIZATION_SUPPORT\n"); #else /* NO_CAPITALIZATION_SUPPORT */ (void) printf ("\t!NO_CAPITALIZATION_SUPPORT\n"); #endif /* NO_CAPITALIZATION_SUPPORT */ #ifdef NO_STDLIB_H (void) printf ("\tNO_STDLIB_H\n"); #else /* NO_STDLIB_H */ (void) printf ("\t!NO_STDLIB_H (STDLIB_H)\n"); #endif /* NO_STDLIB_H */ #ifdef NO8BIT (void) printf ("\tNO8BIT\n"); #else /* NO8BIT */ (void) printf ("\t!NO8BIT (8BIT)\n"); #endif /* NO8BIT */ (void) printf ("\tNRSPECIAL = \"%s\"\n", NRSPECIAL); (void) printf ("\tOLDPAFF = \"%s\"\n", OLDPAFF); (void) printf ("\tOLDPDICT = \"%s\"\n", OLDPDICT); (void) printf ("\tPDICTVAR = \"%s\"\n", PDICTVAR); #ifdef PIECEMEAL_HASH_WRITES (void) printf ("\tPIECEMEAL_HASH_WRITES\n"); #else /* PIECEMEAL_HASH_WRITES */ (void) printf ("\t!PIECEMEAL_HASH_WRITES\n"); #endif /* PIECEMEAL_HASH_WRITES */ #if TERM_MODE != CBREAK (void) printf ("\tRAW\n"); #endif /* TERM_MODE */ #ifdef REGEX_LOOKUP (void) printf ("\tREGEX_LOOKUP\n"); #else /* REGEX_LOOKUP */ (void) printf ("\t!REGEX_LOOKUP\n"); #endif /* REGEX_LOOKUP */ (void) printf ("\tREGLIB = \"%s\"\n", REGLIB); (void) printf ("\tSIGNAL_TYPE = %s\n", SIGNAL_TYPE_STRING); (void) printf ("\tSORTPERSONAL = %d\n", SORTPERSONAL); (void) printf ("\tTEMPNAME = \"%s\"\n", TEMPNAME); (void) printf ("\tTERMLIB = \"%s\"\n", TERMLIB); (void) printf ("\tTEXINFODIR = \"%s\"\n", TEXINFODIR); (void) printf ("\tTEXSPECIAL = \"%s\"\n", TEXSPECIAL); #ifdef TRUNCATEBAK (void) printf ("\tTRUNCATEBAK\n"); #else /* TRUNCATEBAK */ (void) printf ("\t!TRUNCATEBAK\n"); #endif /* TRUNCATEBAK */ #ifdef USESH (void) printf ("\tUSESH\n"); #else /* USESH */ (void) printf ("\t!USESH\n"); #endif /* USESH */ (void) printf ("\tWORDS = \"%s\"\n", WORDS); (void) printf ("\tYACC = \"%s\"\n", YACC); } exit (0); break; case 'n': if (arglen > 2) usage (); tflag = 0; /* nroff/troff mode */ deftflag = 0; if (preftype == NULL) preftype = "nroff"; break; case 't': /* TeX mode */ if (arglen > 2) usage (); tflag = 1; deftflag = 1; if (preftype == NULL) preftype = "tex"; break; case 'T': /* Set preferred file type */ p = (*argv)+2; if (*p == '\0') { argv++; argc--; if (argc == 0) usage (); p = *argv; } preftype = p; break; case 'A': if (arglen > 2) usage (); incfileflag = 1; aflag = 1; break; case 'a': if (arglen > 2) usage (); aflag++; break; case 'D': if (arglen > 2) usage (); dumpflag++; nodictflag++; break; case 'e': if (arglen > 3) usage (); eflag = 1; if ((*argv)[2] == 'e') eflag = 2; else if ((*argv)[2] >= '1' && (*argv)[2] <= '4') eflag = (*argv)[2] - '0'; else if ((*argv)[2] != '\0') usage (); nodictflag++; break; case 'c': if (arglen > 2) usage (); cflag++; lflag++; nodictflag++; break; case 'b': if (arglen > 2) usage (); xflag = 0; /* Keep a backup file */ break; case 'x': if (arglen > 2) usage (); xflag = 1; /* Don't keep a backup file */ break; case 'f': fflag++; p = (*argv)+2; if (*p == '\0') { argv++; argc--; if (argc == 0) usage (); p = *argv; } askfilename = p; if (*askfilename == '\0') askfilename = NULL; break; case 'L': p = (*argv)+2; if (*p == '\0') { argv++; argc--; if (argc == 0) usage (); p = *argv; } contextsize = atoi (p); break; case 'l': if (arglen > 2) usage (); lflag++; break; #ifndef USG case 's': if (arglen > 2) usage (); sflag++; break; #endif case 'S': if (arglen > 2) usage (); sortit = 0; break; case 'B': /* -B: report missing blanks */ if (arglen > 2) usage (); compoundflag = COMPOUND_NEVER; break; case 'C': /* -C: compound words are acceptable */ if (arglen > 2) usage (); compoundflag = COMPOUND_ANYTIME; break; case 'P': /* -P: don't gen non-dict poss's */ if (arglen > 2) usage (); tryhardflag = 0; break; case 'm': /* -m: make all poss affix combos */ if (arglen > 2) usage (); tryhardflag = 1; break; case 'N': /* -N: suppress minimenu */ if (arglen > 2) usage (); minimenusize = 0; break; case 'M': /* -M: force minimenu */ if (arglen > 2) usage (); minimenusize = 2; break; case 'p': cpd = (*argv)+2; if (*cpd == '\0') { argv++; argc--; if (argc == 0) usage (); cpd = *argv; if (*cpd == '\0') cpd = NULL; } LibDict = NULL; break; case 'd': p = (*argv)+2; if (*p == '\0') { argv++; argc--; if (argc == 0) usage (); p = *argv; } if (index (p, '/') != NULL) (void) strcpy (hashname, p); else (void) sprintf (hashname, "%s/%s", LIBDIR, p); if (cpd == NULL && *p != '\0') LibDict = p; p = rindex (p, '.'); if (p != NULL && strcmp (p, ".hash") == 0) *p = '\0'; /* Don't want ext. in LibDict */ else (void) strcat (hashname, ".hash"); break; case 'V': /* Display 8-bit characters as M-xxx */ if (arglen > 2) usage (); vflag = 1; break; case 'w': wchars = (*argv)+2; if (*wchars == '\0') { argv++; argc--; if (argc == 0) usage (); wchars = *argv; } break; case 'W': if ((*argv)[2] == '\0') { argv++; argc--; if (argc == 0) usage (); minword = atoi (*argv); } else minword = atoi (*argv + 2); break; default: usage (); } argv++; argc--; } if (!argc && !lflag && !aflag && !eflag && !dumpflag) usage (); /* * Because of the high cost of reading the dictionary, we stat * the files specified first to see if they exist. If at least * one exists, we continue. */ for (argno = 0; argno < argc; argno++) { if (access (argv[argno], 4) >= 0) break; } if (argno >= argc && !lflag && !aflag && !eflag && !dumpflag) { (void) fprintf (stderr, argc == 1 ? ISPELL_C_NO_FILE : ISPELL_C_NO_FILES); exit (1); } if (linit () < 0) exit (1); if (preftype != NULL) { prefstringchar = findfiletype (preftype, 1, deftflag < 0 ? &deftflag : (int *) NULL); if (prefstringchar < 0 && strcmp (preftype, "tex") != 0 && strcmp (preftype, "nroff") != 0) { (void) fprintf (stderr, ISPELL_C_BAD_TYPE, preftype); exit (1); } } if (prefstringchar < 0) defdupchar = 0; else defdupchar = prefstringchar; if (compoundflag < 0) compoundflag = hashheader.compoundflag; if (tryhardflag < 0) tryhardflag = hashheader.defhardflag; initckch(wchars); if (LibDict == NULL) { (void) strcpy (libdictname, DEFHASH); LibDict = libdictname; p = rindex (libdictname, '.'); if (p != NULL && strcmp (p, ".hash") == 0) *p = '\0'; /* Don't want ext. in LibDict */ } if (!nodictflag) treeinit (cpd, LibDict); if (aflag) { askmode (); treeoutput (); exit (0); } else if (eflag) { expandmode (eflag); exit (0); } else if (dumpflag) { dumpmode (); exit (0); } setbuf (stdout, outbuf); if (lflag) { infile = stdin; outfile = stdout; checkfile (); exit (0); } terminit (); while (argc--) dofile (*argv++); done (0); /* NOTREACHED */ return 0; } static void dofile (filename) char * filename; { struct stat statbuf; char * cp; currentfile = filename; /* See if the file is a .tex file. If so, set the appropriate flags. */ tflag = deftflag; if (tflag < 0) tflag = (cp = rindex (filename, '.')) != NULL && strcmp (cp, ".tex") == 0; if (prefstringchar < 0) { defdupchar = findfiletype (filename, 0, deftflag < 0 ? &tflag : (int *) NULL); if (defdupchar < 0) defdupchar = 0; } if ((infile = fopen (filename, "r")) == NULL) { (void) fprintf (stderr, CANT_OPEN, filename); (void) sleep ((unsigned) 2); return; } readonly = access (filename, 2) < 0; if (readonly) { (void) fprintf (stderr, ISPELL_C_CANT_WRITE, filename); (void) sleep ((unsigned) 2); } (void) fstat (fileno (infile), &statbuf); (void) strcpy (tempfile, TEMPNAME); (void) mktemp (tempfile); if ((outfile = fopen (tempfile, "w")) == NULL) { (void) fprintf (stderr, CANT_CREATE, tempfile); (void) sleep ((unsigned) 2); return; } (void) chmod (tempfile, statbuf.st_mode); quit = 0; changes = 0; checkfile (); (void) fclose (infile); (void) fclose (outfile); if (!cflag) treeoutput (); if (changes && !readonly) update_file (filename, &statbuf); (void) unlink (tempfile); } static void update_file (filename, statbuf) char * filename; struct stat * statbuf; { char bakfile[MAXPATHLEN]; int c; #ifdef TRUNCATEBAK int maxlen; #endif /* TRUNCATEBAK */ char * pathtail; if ((infile = fopen (tempfile, "r")) == NULL) { (void) fprintf (stderr, ISPELL_C_TEMP_DISAPPEARED, tempfile); (void) sleep ((unsigned) 2); return; } #ifdef TRUNCATEBAK (void) strncpy (bakfile, filename, sizeof bakfile - 1); bakfile[sizeof bakfile - 1] = '\0'; if (strcmp(BAKEXT, filename + strlen(filename) - sizeof BAKEXT - 1) != 0) { maxlen = MAXNAMLEN - strlen (BAKEXT); pathtail = rindex (bakfile, '/'); if (pathtail == NULL) pathtail = bakfile; else pathtail++; if (strlen (pathtail) > MAXNAMLEN - sizeof BAKEXT - 1) pathtail[MAXNAMLEN - sizeof BAKEXT -1] = '\0'; (void) strcat (pathtail, BAKEXT); } #else (void) sprintf (bakfile, "%.*s%s", (int) (sizeof bakfile - sizeof BAKEXT), filename, BAKEXT); #endif pathtail = rindex (bakfile, '/'); if (pathtail == NULL) pathtail = bakfile; else pathtail++; if (strncmp (pathtail, bakfile, MAXNAMLEN) != 0) (void) unlink (bakfile); /* unlink so we can write a new one. */ if (link (filename, bakfile) == 0) (void) unlink (filename); /* if we can't write new, preserve .bak regardless of xflag */ if ((outfile = fopen (filename, "w")) == NULL) { (void) fprintf (stderr, CANT_CREATE, filename); (void) sleep ((unsigned) 2); return; } (void) chmod (filename, statbuf->st_mode); while ((c = getc (infile)) != EOF) (void) putc (c, outfile); (void) fclose (infile); (void) fclose (outfile); if (xflag && strncmp (pathtail, bakfile, MAXNAMLEN) != 0) (void) unlink (bakfile); } static void expandmode (option) int option; /* How to print: */ /* 1 = expansions only */ /* 2 = original line + expansions */ /* 3 = original paired w/ expansions */ /* 4 = add length ratio */ { char buf[BUFSIZ]; int explength; /* Total length of all expansions */ register char * flagp; /* Pointer to next flag char */ ichar_t ibuf[BUFSIZ]; MASKTYPE mask[MASKSIZE]; char origbuf[BUFSIZ]; /* Original contents of buf */ char ratiobuf[20]; /* Expansion/root length ratio */ int rootlength; /* Length of root word */ register int temp; while (xgets (buf, sizeof buf, stdin) != NULL) { rootlength = strlen (buf); if (buf[rootlength - 1] == '\n') buf[--rootlength] = '\0'; (void) strcpy (origbuf, buf); if ((flagp = index (buf, hashheader.flagmarker)) != NULL) { rootlength = flagp - buf; *flagp++ = '\0'; } if (option == 2 || option == 3 || option == 4) (void) printf ("%s ", origbuf); if (flagp != NULL) { if (flagp - buf > INPUTWORDLEN) buf[INPUTWORDLEN] = '\0'; } else { if ((int) strlen (buf) > INPUTWORDLEN - 1) buf[INPUTWORDLEN] = '\0'; } (void) fputs (buf, stdout); if (flagp != NULL) { (void) bzero ((char *) mask, sizeof (mask)); while (*flagp != '\0' && *flagp != '\n') { #if MASKBITS <= 32 temp = CHARTOBIT (mytoupper (chartoichar (*flagp))); #else temp = CHARTOBIT ((unsigned char) *flagp); #endif if (temp >= 0 && temp <= LARGESTFLAG) SETMASKBIT (mask, temp); flagp++; /* Accept old-format dicts with extra slashes */ if (*flagp == hashheader.flagmarker) flagp++; } if (strtoichar (ibuf, buf, sizeof ibuf, 1)) (void) fprintf (stderr, WORD_TOO_LONG (buf)); explength = expand_pre (origbuf, ibuf, mask, option, ""); explength += expand_suf (origbuf, ibuf, mask, 0, option, ""); explength += rootlength; if (option == 4) { (void) sprintf (ratiobuf, " %f", (double) explength / (double) rootlength); (void) fputs (ratiobuf, stdout); (void) expand_pre (origbuf, ibuf, mask, 3, ratiobuf); (void) expand_suf (origbuf, ibuf, mask, 0, 3, ratiobuf); } } (void) putchar ('\n'); } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.