home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Product / Product.zip / ISPSRC.ZIP / ispell.h < prev    next >
C/C++ Source or Header  |  1992-10-05  |  26KB  |  719 lines

  1. /* -*- Mode: Text -*- */
  2.  
  3. /*
  4.  * Copyright 1987, 1988, 1989, by Geoff Kuenning, Manhattan Beach, CA
  5.  * Permission for non-profit use is hereby granted.
  6.  * All other rights reserved.
  7.  * See "version.h" for a more complete copyright notice.
  8.  */
  9.  
  10. /*
  11.  * $Id: ispell.h,v 1.41 1991/12/09 00:41:05 geoff Exp $
  12.  *
  13.  * $Log: ispell.h,v $
  14.  * Revision 1.41  1991/12/09  00:41:05  geoff
  15.  * Explicitly initialize tempfile to the null string, since we depend on
  16.  * this initialization.  (Not strictly necessary, but I prefer to make it
  17.  * obvious that this initial value is required.)
  18.  *
  19.  * Revision 1.40  91/09/12  00:01:47  geoff
  20.  * Add definitions and header-file fields for the new TeX special
  21.  * characters.
  22.  * 
  23.  * Revision 1.39  91/09/11  23:22:46  geoff
  24.  * Add TeX_comment.
  25.  * 
  26.  * Revision 1.38  91/08/10  16:38:30  geoff
  27.  * Add vflag.  Remove the typecasts in the ctype-style stuff, since they
  28.  * were unneeded and wrong.
  29.  * 
  30.  * Revision 1.37  91/08/10  14:09:36  geoff
  31.  * Fix all of the ctype-style macros to properly typecast the character
  32.  * before testing it.  Remove the lengthofchar macro.  Change the
  33.  * *isstringch macros to allow stringchars to be only one character long.
  34.  * 
  35.  * Revision 1.36  91/07/15  19:27:03  geoff
  36.  * Change all of the stringchar macros (*isstringch and lengthofchar) to
  37.  * accept a "canonical" parameter and pass it to stringcharlen.
  38.  * 
  39.  * Revision 1.35  91/07/11  19:52:14  geoff
  40.  * Include stdio.h for the definition of BUFSIZ.
  41.  * 
  42.  * Revision 1.34  91/07/05  19:51:45  geoff
  43.  * Add a proper declaration of done(), and remove the unused vb variable.
  44.  * 
  45.  * Revision 1.33  91/07/03  18:20:50  geoff
  46.  * Add the chartoichar macro for conversion between chars and ichar_t's.
  47.  * Add the "ti" and "te" terminal capabilities.
  48.  * 
  49.  * Revision 1.32  91/05/27  21:47:58  geoff
  50.  * Add data-structure support for the string-character type tables.
  51.  * 
  52.  * Revision 1.31  90/12/31  00:59:47  geoff
  53.  * Reformat to follow a consistent convention throughout ispell
  54.  * 
  55.  * Revision 1.30  90/10/14  01:51:39  geoff
  56.  * Add the "changes" and "readonly" variables.
  57.  * 
  58.  * Revision 1.29  90/04/26  22:44:06  geoff
  59.  * Add fields and variables needed to support alternate string characters.
  60.  * 
  61.  * Revision 1.28  89/12/27  22:29:08  geoff
  62.  * Add minword.
  63.  * 
  64.  * Revision 1.27  89/07/11  00:24:11  geoff
  65.  * Add Amiga and REGEX_LOOKUP support from luis@rice.edu.
  66.  * 
  67.  * Revision 1.26  89/07/07  23:26:29  geoff
  68.  * Add a complete set of external declarations, including using the
  69.  * new INIT macro to handle initialized declarations.
  70.  * 
  71.  * Revision 1.25  89/06/09  15:54:45  geoff
  72.  * Add some lint ifdefs, so that the various macros can be checked by
  73.  * lint.  Move the isXXXX macros to ispell.h from config.h, since they
  74.  * shouldn't be changed during configuration.  Add support for the
  75.  * internal "character" type, ichar_t.
  76.  * 
  77.  * Revision 1.24  89/04/28  01:11:16  geoff
  78.  * Change Header to Id;  nobody cares about my pathnames.
  79.  * 
  80.  * Revision 1.23  89/04/03  01:56:34  geoff
  81.  * Add support for string characters.  Fix the magic number to be constant,
  82.  * and put the compilations in the hash header separately.
  83.  * 
  84.  * Revision 1.22  89/02/22  23:16:18  geoff
  85.  * Add "contextsize" to the list of globals.
  86.  * 
  87.  * Revision 1.21  89/02/20  22:10:36  geoff
  88.  * Define ALLFLAGS even if CAPITALIZATION is turned off.
  89.  * 
  90.  * Revision 1.20  89/02/06  02:21:38  geoff
  91.  * Fix the offsets of TEX's left and right curlies and parens to match
  92.  * what the documentation specifies for the "texchars" statement.
  93.  * 
  94.  * Revision 1.19  88/12/26  02:29:52  geoff
  95.  * Add a copyright notice.
  96.  * 
  97.  * Revision 1.18  88/11/25  19:52:38  geoff
  98.  * Fix the SET/CLR/TSTMASKBIT macros to work correctly with masks of more
  99.  * than 32 bits.
  100.  * 
  101.  * Revision 1.17  88/06/25  17:50:05  geoff
  102.  * Add hash header fields for the defaults set in the affix file:  nroff
  103.  * and troff control characters, compound word (missing space) flag, and
  104.  * automatic affix-generation (try hard) flag.  Update the magic number
  105.  * to reflect the change in hash formats.
  106.  * 
  107.  * Revision 1.16  88/04/30  22:14:12  geoff
  108.  * Get rid of a bunch of unused termcap variables detected by lint.
  109.  * 
  110.  * Revision 1.15  88/02/20  23:12:48  geoff
  111.  * Expand the handling of MASKBITS to provide more size options.  Redo the
  112.  * capitalization handling structures.  Change the magic number and its
  113.  * creation so that binary-incompatible configuration options will cause
  114.  * differing magic numbers.  Add "struct success" to describe spelling
  115.  * hits.  Add some new externals and delete some unused one.
  116.  * 
  117.  * Revision 1.14  87/09/30  23:30:51  geoff
  118.  * Make the sort order a short so it can go past the range of a char.  Add
  119.  * a bunch of globals that used to be scattered through .c files, plus
  120.  * one or two new ones to support the "nopossibilities" stuff.
  121.  * 
  122.  * Revision 1.13  87/09/09  00:18:45  geoff
  123.  * Add sortval and sortorder to the hash header.
  124.  * 
  125.  * Revision 1.12  87/09/03  23:17:30  geoff
  126.  * Get rid of a spurious WORDLEN definition, and use a different magic
  127.  * number for NO8BIT hash files.
  128.  * 
  129.  * Revision 1.11  87/07/20  23:22:44  geoff
  130.  * Major changes to support table driving.  Highlights include macros
  131.  * to support the new flag bits, removal of the X_flag fields from the
  132.  * table entry and replacement with the lumped masks, addition of language
  133.  * tables, and using a different magic number if CAPITALIZE is defined.
  134.  * 
  135.  * Revision 1.10  87/06/27  12:20:32  geoff
  136.  * Add the "sg" termcap entry for braindamaged terminals.
  137.  * 
  138.  * Revision 1.9  87/04/19  22:52:54  geoff
  139.  * Add fields for capitalization handling.  Update MAGIC so it will refuse to
  140.  * work with uncapitalized hash files.  Make hashheader a global.
  141.  * 
  142.  * Revision 1.8  87/04/01  15:22:48  geoff
  143.  * Integrate Joe Orost's V7/register changes into the main branch
  144.  * 
  145.  * Revision 1.7  87/03/22  23:56:32  geoff
  146.  * Fix minor bugs found by Dave Mason
  147.  * 
  148.  * Revision 1.6  87/03/01  00:56:50  geoff
  149.  * Get rid of struct node;  add keep flag to struct dent, and delete
  150.  * some excess stuff caused by bad patching.
  151.  * 
  152.  * Revision 1.5  87/02/28  14:58:21  geoff
  153.  * Add a full struct dent to the tree node structure.
  154.  * 
  155.  * Revision 1.4  87/02/26  00:31:07  geoff
  156.  * Integrate McQueer's enhancements into the main branch
  157.  * 
  158.  * Revision 1.3  87/01/19  00:06:41  geoff
  159.  * Move LIBDIR to where I keep it.
  160.  * 
  161.  * Revision 1.2  87/01/17  13:11:53  geoff
  162.  * Add RCS ID keywords
  163.  * 
  164.  */
  165.  
  166. #include <stdio.h>
  167.  
  168. #ifdef NO8BIT
  169. #define SET_SIZE    128
  170. #else
  171. #define SET_SIZE    256
  172. #endif
  173.  
  174. #define MASKTYPE    long
  175. #define MASKTYPE_WIDTH    (8 * sizeof (MASKTYPE))
  176. #define MASKSIZE    (MASKBITS / MASKTYPE_WIDTH)
  177.  
  178. /* The following is really testing for MASKSIZE <= 1, but cpp can't do that */
  179. #ifndef lint
  180. #if MASKBITS <= 32
  181. #define SETMASKBIT(mask, bit) ((mask)[0] |= 1 << (bit))
  182. #define CLRMASKBIT(mask, bit) ((mask)[0] &= ~(1 << (bit)))
  183. #define TSTMASKBIT(mask, bit) ((mask)[0] & (1 << (bit)))
  184. #else
  185. #define SETMASKBIT(mask, bit) \
  186.             ((mask)[(bit) / MASKTYPE_WIDTH] |= \
  187.               1 << ((bit) & (MASKTYPE_WIDTH - 1)))
  188. #define CLRMASKBIT(mask, bit) \
  189.             ((mask)[(bit) / MASKTYPE_WIDTH] &= \
  190.               ~(1 << ((bit) & (MASKTYPE_WIDTH - 1))))
  191. #define TSTMASKBIT(mask, bit) \
  192.             ((mask)[(bit) / MASKTYPE_WIDTH] & \
  193.               (1 << ((bit) & (MASKTYPE_WIDTH - 1))))
  194. #endif
  195. #endif /* lint */
  196.  
  197. #if MASKBITS > 64
  198. #define FULLMASKSET
  199. #endif
  200.  
  201. #if MASKBITS <= 32
  202. # ifndef lint
  203. #define BITTOCHAR(bit)    ((bit) + 'A')
  204. #define CHARTOBIT(ch)    ((ch) - 'A')
  205. # endif /* lint */
  206. #define LARGESTFLAG    26    /* 5 are needed for flagfield below */
  207. #define FLAGBASE    26
  208. #else
  209. # if MASKBITS <= 64
  210. #  ifndef lint
  211. #define BITTOCHAR(bit)    ((bit) + 'A')
  212. #define CHARTOBIT(ch)    ((ch) - 'A')
  213. #  endif /* lint */
  214. #define LARGESTFLAG    (64 - 6) /* 5 are needed for flagfield below */
  215. #define FLAGBASE    26
  216. # else
  217. #  ifndef lint
  218. #define BITTOCHAR(bit)    (bit)
  219. #define CHARTOBIT(ch)    (ch)
  220. #  endif /* lint */
  221. #define LARGESTFLAG    MASKBITS /* flagfield is a separate field */
  222. #define FLAGBASE    0
  223. # endif
  224. #endif
  225.  
  226. /*
  227. ** Data type for internal word storage.  If necessary, we use shorts rather
  228. ** than chars so that string characters can be encoded as a single unit.
  229. */
  230. #if (SET_SIZE + MAXSTRINGCHARS) <= 256
  231. #ifndef lint
  232. #define ICHAR_IS_CHAR
  233. #endif /* lint */
  234. #endif
  235.  
  236. #ifdef ICHAR_IS_CHAR
  237. typedef unsigned char    ichar_t;    /* Internal character */
  238. #define icharlen    strlen
  239. #define icharcpy    strcpy
  240. #define icharcmp    strcmp
  241. #define icharncmp    strncmp
  242. #define chartoichar(x)    ((ichar_t) (x))
  243. #else
  244. typedef unsigned short    ichar_t;    /* Internal character */
  245. #define chartoichar(x)    ((ichar_t) (unsigned char) (x))
  246. #endif
  247.  
  248. struct dent
  249.     {
  250.     struct dent *    next;
  251.     char *        word;
  252.     MASKTYPE        mask[MASKSIZE];
  253. #ifdef FULLMASKSET
  254.     char        flags;
  255. #endif
  256.     };
  257.  
  258. /*
  259. ** Flags in the directory entry.  If FULLMASKSET is undefined, these are
  260. ** stored in the highest bits of the last longword of the mask field.  If
  261. ** FULLMASKSET is defined, they are stored in the extra "flags" field.
  262. #ifdef CAPITALIZATION
  263. **
  264. ** If a word has only one capitalization form, and that form is not
  265. ** FOLLOWCASE, it will have exactly one entry in the dictionary.  The
  266. ** legal capitalizations will be indicated by the 2-bit capitalization
  267. ** field, as follows:
  268. **
  269. **    ALLCAPS        The word must appear in all capitals.
  270. **    CAPITALIZED    The word must be capitalized (e.g., London).
  271. **            It will also be accepted in all capitals.
  272. **    ANYCASE        The word may appear in lowercase, capitalized,
  273. **            or all-capitals.
  274. **
  275. ** Regardless of the capitalization flags, the "word" field of the entry
  276. ** will point to an all-uppercase copy of the word.  This is to simplify
  277. ** the large portion of the code that doesn't care about capitalization.
  278. ** Ispell will generate the correct version when needed.
  279. **
  280. ** If a word has more than one capitalization, there will be multiple
  281. ** entries for it, linked together by the "next" field.  The initial
  282. ** entry for such words will be a dummy entry, primarily for use by code
  283. ** that ignores capitalization.  The "word" field of this entry will
  284. ** again point to an all-uppercase copy of the word.  The "mask" field
  285. ** will contain the logical OR of the mask fields of all variants.
  286. ** A header entry is indicated by a capitalization type of ALLCAPS,
  287. ** with the MOREVARIANTS bit set.
  288. **
  289. ** The following entries will define the individual variants.  Each
  290. ** entry except the last has the MOREVARIANTS flag set, and each
  291. ** contains one of the following capitalization options:
  292. **
  293. **    ALLCAPS        The word must appear in all capitals.
  294. **    CAPITALIZED    The word must be capitalized (e.g., London).
  295. **            It will also be accepted in all capitals.
  296. **    FOLLOWCASE    The word must be capitalized exactly like the
  297. **            sample in the entry.  Prefix (suffix) characters
  298. **            must be rendered in the case of the first (last)
  299. **            "alphabetic" character.  It will also be accepted
  300. **            in all capitals.  ("Alphabetic" means "mentioned
  301. **            in a 'casechars' statement".)
  302. **    ANYCASE        The word may appear in lowercase, capitalized,
  303. **            or all-capitals.
  304. **
  305. ** The "mask" field for the entry contains only the affix flag bits that
  306. ** are legal for that capitalization.  The "word" field will be null
  307. ** except for FOLLOWCASE entries, where it will point to the
  308. ** correctly-capitalized spelling of the root word.
  309. **
  310. ** It is worth discussing why the ALLCAPS option is used in
  311. ** the header entry.  The header entry accepts an all-capitals
  312. ** version of the root plus every affix (this is always legal, since
  313. ** words get capitalized in headers and so forth).  Further, all of
  314. ** the following variant entries will reject any all-capitals form
  315. ** that is illegal due to an affix.
  316. **
  317. ** Finally, note that variations in the KEEP flag can cause a multiple-variant
  318. ** entry as well.  For example, if the personal dictionary contains "ALPHA",
  319. ** (KEEP flag set) and the user adds "alpha" with the KEEP flag clear, a
  320. ** multiple-variant entry will be created so that "alpha" will be accepted
  321. ** but only "ALPHA" will actually be kept.
  322. #endif
  323. */
  324. #ifdef FULLMASKSET
  325. #define flagfield    flags
  326. #else
  327. #define flagfield    mask[MASKSIZE - 1]
  328. #endif
  329. #define USED        (1 << (FLAGBASE + 0))
  330. #define KEEP        (1 << (FLAGBASE + 1))
  331. #ifdef CAPITALIZATION
  332. #define ANYCASE        (0 << (FLAGBASE + 2))
  333. #define ALLCAPS        (1 << (FLAGBASE + 2))
  334. #define CAPITALIZED    (2 << (FLAGBASE + 2))
  335. #define FOLLOWCASE    (3 << (FLAGBASE + 2))
  336. #define CAPTYPEMASK    (3 << (FLAGBASE + 2))
  337. #define MOREVARIANTS    (1 << (FLAGBASE + 4))
  338. #define ALLFLAGS    (USED | KEEP | CAPTYPEMASK | MOREVARIANTS)
  339. #define captype(x)    ((x) & CAPTYPEMASK)
  340. #else /* CAPITALIZATION */
  341. #define ALLFLAGS    (USED | KEEP)
  342. #endif /* CAPITALIZATION */
  343.  
  344. /*
  345.  * Language tables used to encode prefix and suffix information.
  346.  */
  347. struct flagent
  348.     {
  349.     ichar_t *        strip;            /* String to strip off */
  350.     ichar_t *        affix;            /* Affix to append */
  351.     short        flagbit;        /* Flag bit this ent matches */
  352.     short        stripl;            /* Length of strip */
  353.     short        affl;            /* Length of affix */
  354.     short        numconds;        /* Number of char conditions */
  355.     short        flagflags;        /* Modifiers on this flag */
  356.     char        conds[SET_SIZE + MAXSTRINGCHARS]; /* Adj. char conds */
  357.     };
  358.  
  359. /*
  360.  * Bits in flagflags
  361.  */
  362. #define FF_CROSSPRODUCT    (1 << 0)        /* Affix does cross-products */
  363.  
  364. union ptr_union                    /* Aid for building flg ptrs */
  365.     {
  366.     struct flagptr *    fp;            /* Pointer to more indexing */
  367.     struct flagent *    ent;            /* First of a list of ents */
  368.     };
  369.  
  370. struct flagptr
  371.     {
  372.     union ptr_union    pu;            /* Ent list or more indexes */
  373.     int            numents;        /* If zero, pu.fp is valid */
  374.     };
  375.  
  376. /*
  377.  * Description of a single string character type.
  378.  */
  379. struct strchartype
  380.     {
  381.     char *        name;            /* Name of the type */
  382.     char *        suffixes;        /* File suffixes, null seps */
  383.     };
  384.  
  385. /*
  386.  * Header placed at the beginning of the hash file.
  387.  */
  388. struct hashheader
  389.     {
  390.     short magic;                                /* Magic number for ID */
  391.     short compileoptions;            /* How we were compiled */
  392.     short maxstringchars;            /* Max # strchrs we support */
  393.     short maxstringcharlen;            /* Max strchr len supported */
  394.     int stringsize;                /* Size of string table */
  395.     int lstringsize;                /* Size of lang. str tbl */
  396.     int tblsize;                /* No. entries in hash tbl */
  397.     int stblsize;                /* No. entries in sfx tbl */
  398.     int ptblsize;                /* No. entries in pfx tbl */
  399.     int sortval;                /* Largest sort ID assigned */
  400.     int nstrchars;                /* No. strchars defined */
  401.     int nstrchartype;                /* No. strchar types */
  402.     int strtypestart;                /* Start of strtype table */
  403.     char nrchars[5];                /* Nroff special characters */
  404.     char texchars[13];                /* TeX special characters */
  405.     char defspaceflag;                /* Default missingspace flag */
  406.     char defhardflag;                /* Default tryveryhard flag */
  407.     char flagmarker;                /* "Start-of-flags" char */
  408.     unsigned short sortorder[SET_SIZE + MAXSTRINGCHARS]; /* Sort ordering */
  409.     ichar_t lowerconv[SET_SIZE + MAXSTRINGCHARS]; /* Lower-conversion table */
  410.     ichar_t upperconv[SET_SIZE + MAXSTRINGCHARS]; /* Upper-conversion table */
  411.     char wordchars[SET_SIZE + MAXSTRINGCHARS]; /* NZ for chars found in wrds */
  412.     char upperchars[SET_SIZE + MAXSTRINGCHARS]; /* NZ for uppercase chars */
  413.     char lowerchars[SET_SIZE + MAXSTRINGCHARS]; /* NZ for lowercase chars */
  414.     char boundarychars[SET_SIZE + MAXSTRINGCHARS]; /* NZ for boundary chars */
  415.     char stringstarts[SET_SIZE];        /* NZ if char can start str */
  416.     char stringchars[MAXSTRINGCHARS][MAXSTRINGCHARLEN + 1]; /* String chars */
  417.     char stringdups[MAXSTRINGCHARS];        /* No. of "base" char */
  418.     char dupnos[MAXSTRINGCHARS];        /* Dup char ID # */
  419.     };
  420.  
  421. /* hash table magic number */
  422. #define MAGIC            0x9601
  423.  
  424. /* compile options, put in the hash header for consistency checking */
  425. #ifdef NO8BIT
  426. # define MAGIC8BIT        0x01
  427. #else
  428. # define MAGIC8BIT        0x00
  429. #endif
  430. #ifdef CAPITALIZATION
  431. # define MAGICCAPITALIZATION    0x02
  432. #else
  433. # define MAGICCAPITALIZATION    0x00
  434. #endif
  435. #if MASKBITS <= 32
  436. # define MAGICMASKSET        0x00
  437. #else
  438. # if MASKBITS <= 64
  439. #  define MAGICMASKSET        0x04
  440. # else
  441. #  if MASKBITS <= 128
  442. #   define MAGICMASKSET        0x08
  443. #  else
  444. #   define MAGICMASKSET        0x0C
  445. #  endif
  446. # endif
  447. #endif
  448.  
  449. #define COMPILEOPTIONS    (MAGIC8BIT | MAGICCAPITALIZATION | MAGICMASKSET)
  450.  
  451. /*
  452.  * Structure used to record data about successful lookups; these values
  453.  * are used in the ins_root_cap routine to produce correct capitalizations.
  454.  */
  455. struct success
  456.     {
  457.     struct dent *    dictent;    /* Header of dict entry chain for wd */
  458.     struct flagent *    prefix;        /* Prefix flag used, or NULL */
  459.     struct flagent *    suffix;        /* Suffix flag used, or NULL */
  460.     };
  461.  
  462. /*
  463. ** Offsets into the nroff special-character array
  464. */
  465. #define NRLEFTPAREN    hashheader.nrchars[0]
  466. #define NRRIGHTPAREN    hashheader.nrchars[1]
  467. #define NRDOT        hashheader.nrchars[2]
  468. #define NRBACKSLASH    hashheader.nrchars[3]
  469. #define NRSTAR        hashheader.nrchars[4]
  470.  
  471. /*
  472. ** Offsets into the TeX special-character array
  473. */
  474. #define TEXLEFTPAREN    hashheader.texchars[0]
  475. #define TEXRIGHTPAREN    hashheader.texchars[1]
  476. #define TEXLEFTSQUARE    hashheader.texchars[2]
  477. #define TEXRIGHTSQUARE    hashheader.texchars[3]
  478. #define TEXLEFTCURLY    hashheader.texchars[4]
  479. #define TEXRIGHTCURLY    hashheader.texchars[5]
  480. #define TEXLEFTANGLE    hashheader.texchars[6]
  481. #define TEXRIGHTANGLE    hashheader.texchars[7]
  482. #define TEXBACKSLASH    hashheader.texchars[8]
  483. #define TEXDOLLAR    hashheader.texchars[9]
  484. #define TEXSTAR        hashheader.texchars[10]
  485. #define TEXDOT        hashheader.texchars[11]
  486. #define TEXPERCENT    hashheader.texchars[12]
  487.  
  488. /*
  489. ** The isXXXX macros normally only check ASCII range, and don't support
  490. ** the character sets of other languages.  These private versions handle
  491. ** whatever character sets have been defined in the affix files.
  492. */
  493. #ifdef lint
  494. extern ichar_t mytolower ();
  495. extern ichar_t mytoupper ();
  496. #else /* lint */
  497. #define myupper(X)    (hashheader.upperchars[X])
  498. #define mylower(X)    (hashheader.lowerchars[X])
  499. #define myspace(X)    (((X) > 0)  &&  ((X) < 0x80) \
  500.               &&  isspace((unsigned char) (X)))
  501. #define iswordch(X)    (hashheader.wordchars[X])
  502. #define isboundarych(X) (hashheader.boundarychars[X])
  503. #define isstringstart(X) (hashheader.stringstarts[(unsigned char) (X)])
  504. #define mytolower(X)    (hashheader.lowerconv[X])
  505. #define mytoupper(X)    (hashheader.upperconv[X])
  506. #endif /* lint */
  507.  
  508. /*
  509. ** These macros are similar to the ones above, but they take into account
  510. ** the possibility of string characters.  Note well that they take a POINTER,
  511. ** not a character.
  512. **
  513. ** The "l_" versions set "len" to the length of the string character as a
  514. ** handy side effect.  (Note that the global "laststringch" is also set,
  515. ** and sometimes used, by these macros.)
  516. **
  517. ** The "l1_" versions go one step further and guarantee that the "len"
  518. ** field is valid for *all* characters, being set to 1 even if the macro
  519. ** returns false.  This macro is a great example of how NOT to write
  520. ** readable C.
  521. */
  522. #define isstringch(ptr, canon)    (isstringstart (*ptr) \
  523.                   &&  stringcharlen (ptr, canon) > 0)
  524. #define l_isstringch(ptr, len, canon)    \
  525.                 (isstringstart (*ptr) \
  526.                   &&  (len = stringcharlen (ptr, canon)) > 0)
  527. #define l1_isstringch(ptr, len, canon)    \
  528.                 (len = 1, \
  529.                   isstringstart (*ptr) \
  530.                     &&  ((len = stringcharlen (ptr, canon)) \
  531.                     > 0 \
  532.                       ? 1 : (len = 1, 0)))
  533.  
  534. #ifdef AMIGA
  535. #ifndef BUILDHASH
  536. #define printf        printcon
  537. #undef putchar
  538. #undef getchar
  539. #define putchar     putccon
  540. #define getchar     getccon
  541. #endif /* BUILDHASH */
  542. #endif /* AMIGA */
  543.  
  544. /*
  545.  * termcap variables
  546.  */
  547. #ifdef MAIN
  548. # define EXTERN /* nothing */
  549. #else
  550. # define EXTERN extern
  551. #endif
  552.  
  553. extern SIGNAL_TYPE    done ();
  554. extern char *        tgetstr ();
  555. extern char *        ichartosstr ();
  556. extern ichar_t *    strtosichar ();
  557. extern char *        printichar ();
  558. extern char *        getline ();
  559. extern void        chupcase ();
  560. extern void        upcase ();
  561. extern void         lowcase ();
  562. #ifdef REGEX_LOOKUP
  563. extern char *        do_regex_lookup ();
  564. #endif /* REGEX_LOOKUP */
  565.  
  566. #ifdef AMIGA 
  567. extern long        _Heapsize;
  568. #endif /* AMIGA */
  569.  
  570. EXTERN char *    BC;    /* backspace if not ^H */
  571. EXTERN char *    cd;    /* clear to end of display */
  572. EXTERN char *    cl;    /* clear display */
  573. EXTERN char *    cm;    /* cursor movement */
  574. EXTERN char *    ho;    /* home */
  575. EXTERN char *    nd;    /* non-destructive space */
  576. EXTERN char *    so;    /* standout */
  577. EXTERN char *    se;    /* standout end */
  578. EXTERN int    sg;    /* space taken by so/se */
  579. EXTERN char *    ti;    /* terminal initialization sequence */
  580. EXTERN char *    te;    /* terminal termination sequence */
  581. EXTERN int    li;    /* lines */
  582. EXTERN int    co;    /* columns */
  583.  
  584. EXTERN int    contextsize;    /* number of lines of context to show */
  585. EXTERN char    contextbufs[MAXCONTEXT][BUFSIZ]; /* Context of current line */
  586. EXTERN char *    currentchar;    /* Location in contextbufs */
  587. EXTERN char    ctoken[INPUTWORDLEN + MAXAFFIXLEN]; /* Current token as char */
  588. EXTERN ichar_t    itoken[INPUTWORDLEN + MAXAFFIXLEN]; /* Ctoken as ichar_t str */
  589.  
  590. EXTERN char    termcap[1024];    /* termcap entry */
  591. EXTERN char    termstr[1024];    /* for string values */
  592. EXTERN char *    termptr;    /* pointer into termcap, used by tgetstr */
  593.  
  594. EXTERN int    numhits;    /* number of hits in dictionary lookups */
  595. EXTERN struct success
  596.         hits[MAX_HITS]; /* table of hits gotten in lookup */
  597.  
  598. EXTERN char *    hashstrings;    /* Strings in hash table */
  599. EXTERN struct hashheader
  600.         hashheader;    /* Header of hash table */
  601. EXTERN struct dent *
  602.         hashtbl;    /* Main hash table, for dictionary */
  603. EXTERN int    hashsize;    /* Size of main hash table */
  604.  
  605. EXTERN char    hashname[MAXPATHLEN]; /* Name of hash table file */
  606.  
  607. EXTERN int    aflag;        /* NZ if -a or -A option specified */
  608. EXTERN int    cflag;        /* NZ if -c (crunch) option */
  609. EXTERN int    lflag;        /* NZ if -l (list) option */
  610. EXTERN int    incfileflag;    /* whether xgets() acts exactly like gets() */
  611. EXTERN int    nodictflag;    /* NZ if dictionary not needed */
  612.  
  613. EXTERN int    erasechar;    /* User's erase character, from stty */
  614. EXTERN int    killchar;    /* User's kill character */
  615.  
  616. EXTERN int    laststringch;    /* Number of last string character */
  617. EXTERN int    defdupchar;    /* Default duplicate string type */
  618.  
  619. EXTERN int    numpflags;        /* Number of prefix flags in table */
  620. EXTERN int    numsflags;        /* Number of suffix flags in table */
  621. EXTERN struct flagptr pflagindex[SET_SIZE + MAXSTRINGCHARS];
  622.                     /* Fast index to pflaglist */
  623. EXTERN struct flagent *    pflaglist;    /* Prefix flag control list */
  624. EXTERN struct flagptr sflagindex[SET_SIZE + MAXSTRINGCHARS];
  625.                     /* Fast index to sflaglist */
  626. EXTERN struct flagent *    sflaglist;    /* Suffix flag control list */
  627.  
  628. EXTERN struct strchartype *        /* String character type collection */
  629.         chartypes;
  630.  
  631. EXTERN FILE *    infile;            /* File being corrected */
  632. EXTERN FILE *    outfile;        /* Corrected copy of infile */
  633.  
  634. EXTERN char *    askfilename;        /* File specified in -f option */
  635.  
  636. EXTERN int    changes;        /* NZ if changes made to cur. file */
  637. EXTERN int    readonly;        /* NZ if current file is readonly */
  638. EXTERN int    quit;            /* NZ if we're done with this file */
  639.  
  640. #define MAXPOSSIBLE    100    /* Max no. of possibilities to generate */
  641.  
  642. EXTERN char    possibilities[MAXPOSSIBLE][INPUTWORDLEN + MAXAFFIXLEN];
  643.                 /* Table of possible corrections */
  644. EXTERN int    pcount;        /* Count of possibilities generated */
  645. EXTERN int    maxposslen;    /* Length of longest possibility */
  646. EXTERN int    easypossibilities; /* Number of "easy" corrections found */
  647.                 /* ..(defined as those using legal affixes) */
  648. /*
  649.  * The following array contains a list of characters that should be tried
  650.  * in "missingletter."  Note that lowercase characters are omitted.
  651.  */
  652. EXTERN int    Trynum;        /* Size of "Try" array */
  653. EXTERN ichar_t    Try[SET_SIZE + MAXSTRINGCHARS];
  654.  
  655.  
  656. /* These variables will contain the settings found in the configuration
  657.  * file ispell.cfg.  Added for os/2 -- jbh  8/24/92
  658.  */
  659. #ifdef OS2
  660. EXTERN char     cfhashname[MAXPATHLEN]; /* Name of hash table file */
  661. EXTERN char     cflibdir[MAXPATHLEN];   /* directory where ispell.exe is */
  662. EXTERN char     cftempname[MAXPATHLEN]; /* temporary filename template */
  663. EXTERN char     cfpersonaldict[MAXPATHLEN]; /* Name of personal dictionary */
  664. EXTERN char     cfsysdict[MAXPATHLEN];  /* Name of system dictionary */
  665. EXTERN char     cfegrepcmd[MAXPATHLEN]; /* command for searching system dict */
  666. #endif  /* OS2 */
  667.  
  668. /*
  669.  * Initialized variables.  These are generated using macros so that they
  670.  * may be consistently declared in all programs.  Numerous examples of
  671.  * usage are given below.
  672.  */
  673. #ifdef MAIN
  674. #define INIT(decl, init)    decl = init
  675. #else
  676. #define INIT(decl, init)    extern decl
  677. #endif
  678.  
  679. #ifdef MINIMENU
  680. INIT (int minimenusize, 2);        /* MUST be either 2 or zero */
  681. #else /* MINIMENU */
  682. INIT (int minimenusize, 0);        /* MUST be either 2 or zero */
  683. #endif /* MINIMENU */
  684.  
  685. INIT (int eflag, 0);            /* NZ for expand mode */
  686. INIT (int dumpflag, 0);            /* NZ to do dump mode */
  687. INIT (int fflag, 0);            /* NZ if -f specified */
  688. #ifndef USG
  689. INIT (int sflag, 0);            /* NZ to stop self after EOF */
  690. #endif
  691. INIT (int vflag, 0);            /* NZ to display characters as M-xxx */
  692. INIT (int xflag, DEFNOBACKUPFLAG);    /* NZ to suppress backups */
  693. INIT (int deftflag, DEFTEXFLAG);    /* NZ for TeX mode by default */
  694. INIT (int tflag, DEFTEXFLAG);        /* NZ for TeX mode in current file */
  695. INIT (int prefstringchar, -1);        /* Preferred string character type */
  696.  
  697. INIT (int terse, 0);            /* NZ for "terse" mode */
  698. INIT (char *LibDict, NULL);        /* Pointer to name of $(LIBDIR)/dict */
  699.  
  700. INIT (char tempfile[MAXPATHLEN], "");    /* Name of file we're spelling into */
  701.  
  702. INIT (int minword, MINWORD);        /* Longest always-legal word */
  703. INIT (int sortit, 1);            /* Sort suggestions alphabetically */
  704. INIT (int missingspaceflag, -1);    /* Don't report missing spaces */
  705. INIT (int tryhardflag, -1);        /* Always call tryveryhard */
  706.  
  707. INIT (char *currentfile, NULL);        /* Name of current input file */
  708.  
  709. /* Odd numbers for math mode in LaTeX; even for LR or paragraph mode */
  710. INIT (int math_mode, 0);
  711. /* P -- paragraph or LR mode
  712.  * b -- parsing a \begin statement
  713.  * e -- parsing an \end statement
  714.  * r -- parsing a \ref type of argument.
  715.  * m -- looking for a \begin{minipage} argument.
  716.  */
  717. INIT (char LaTeX_Mode, 'P');
  718. INIT (int TeX_comment, 0);
  719.