/************************************************************************ * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * * provided to you without charge, and with no warranty. You may give * * away copies of JOVE, including sources, provided that this notice is * * included in all the files. * ************************************************************************/ /* * Modified: Oct 1988 by Tom Hageman * - Word definition in Fundamental mode: all printable characters * - tab is punctuation * - underscore is Word in C mode * Mar 89 [TRH] * - add separate Word, Uppercase and Lowercase conversion tables * - Single character type table. * May 89 [TRH] Atari ST support * Oct 89 [TRH] MS-DOS and international character set support * Jan 90 [TRH] better system parametrization: * Feb 90 [TRH] add IBM line-draw and block characters * Jun 90 [TRH] add ISO Latin 1 character set * Feb 91 [TRH] add Macintosh character set; consider greek part of TEXT word; * - don't consider (') part of TEXT word. * Jun 91 [TRH] add NeXT (2.0 and newer) character set * - add help facility to `accent' * Mar 92 [TRH] include actual character tables so we can build them elsewhere */ #include "tune.h" /* to allow definition of debug flags there. */ #ifdef DEBUG /* General debug flag, turn on file-specific flag. */ # ifndef CTYPE_DEBUG # define CTYPE_DEBUG 1 # endif #else # if CTYPE_DEBUG /* File-specific debug flag, turn on general flag. */ # define DEBUG # endif #endif #include "jove.h" RCS("$Id: ctype.c,v 14.31.0.12 1994/06/23 02:46:24 tom Exp tom $") #define _CTYPE_C_ #include "ctype.h" #define CTABLESIZE (1< 7) * public Const char CaseEquiv[CTABLESIZE] - case equivalence table * For 8-bit character sets, this table is used when searching with * "case-ignore-search" on. Apart from the character case mapping it * also maps accented characters to their non-accented equivalents. * For 7-bit character sets, the uppercase table is used instead. * * private const char * const AccentTab[] - accent definition table. * The Accent table entry has the following structure: * , {, }... #endif * private const char charset_name[] - name of the character-set. */ DEF_STR( "character-set", CharSetName, 40, V_STRING|V_CONST ) _IF(def PRIVATE) = (char *) charset_name; #if (BPC > 7) #ifdef SELECTABLE private const char * const *SelectedAccentTab = AccentTab; # define AccentTab SelectedAccentTab /* for Accent's sake */ #endif /* * Get an accented character. * e.g. bind this to {ESC,C-X} {' ^ ` " ~ , * / _ : ; (| # = % .)} */ DEF_CMD( "accent", Accent, EDIT ) _IF( BPC > 7 ) { extern int alarmed; register const char * const *aa, *a; register int c = LastKeyStruck, pass = 0; /* find accent descriptor */ for (aa = AccentTab;;) { if ((a = *aa++) == NULL) { if (c == '?') { TOstart("*Help*", TRUE); for (aa = AccentTab; a = *aa++; ) Typeout(" %c %s", *a, &a[1]); TOstop(); pass = 0; } if (pass > 0) complain((char *)0); pass++; s_mess("%N: %f ("); for (aa = AccentTab; a = *aa++; ) add_mess("%c", *a); add_mess(") "); c = addgetc(); repl_strokes(mesgbuf); aa = AccentTab; continue; } if (c == *a++) break; } alarmed = 0; repl_strokes(sprint("%s(%s) ", key_strokes(), a)); c = waitchar(); /* find character */ for (;;) { if (*a == '\0') { rbell(); /* not found... */ return; } if (c == *a++) break; a++; /* no match, skip result char */ } Ungetc(*a); Ungetc(QuoteChar); /* to get literal insert */ } #ifdef SELECTABLE # undef AccentTab /* unhide the sucker */ public void set_char_tables(new_char_tables, offset, size, new_accent_table, new_name) const char * const *new_char_tables; int offset, size; const char * const *new_accent_table; const char *new_name; { static char * const tables[NCTABLES] = { CharTable, WordTable, LocTable, CaseEquiv }; static char *saved_tables ZERO; register int i; ASSERT(NCTABLES == sizeof tables / sizeof tables[0]); # if CTYPE_DEBUG if ((unsigned) offset + size > CTABLESIZE) complain("BUG: set_char_tables(\"%s\", off=%d, size=%d)", new_name, offset, size); # endif if (saved_tables == NULL) { /* initialize on first call. */ if (new_char_tables == NULL) /* restore tables is a no-op. */ return; saved_tables = emalloc(NCTABLES * CTABLESIZE); { i = NCTABLES - 1; } do { memcpy(saved_tables + i * CTABLESIZE, tables[i], CTABLESIZE); } while (--i >= 0); } { i = NCTABLES - 1; } do { register int j; register const char *src; register char *dest = tables[i]; /* Restore the original table. */ memcpy(dest, saved_tables + i * CTABLESIZE, CTABLESIZE); if (new_char_tables == NULL || (src = new_char_tables[i]) == NULL) continue; /* Superimpose the new table--if any--over the original, replacing only non-zero values. */ dest += offset; for (j = size; --j >= 0; ) if (src[j]) dest[j] = src[j]; } while (--i >= 0); /* Now build the uppercase table form the lowercase table, by observing that the relation ``toupper(tolower(c)) == c'' should always hold. */ { i = CTABLESIZE - 1; } do { UpcTable[i] = i; } while (--i >= 0); { i = CTABLESIZE - 1; } do { if (tolower(i) != i) UpcTable[tolower(i)] = i; } while (--i >= 0); /* Setting the Accent Table is simple... */ SelectedAccentTab = (new_accent_table) ? new_accent_table : AccentTab; /* ...so is setting the name. */ CharSetName = (char *)((new_name) ? new_name : charset_name); } #endif /* SELECTABLE */ #endif /* (BPC > 7) */ /*====================================================================== * $Log: ctype.c,v $ * Revision 14.31.0.12 1994/06/23 02:46:24 tom * (Accent): fix name of scratch buffer. * * Revision 14.31.0.8 1993/11/11 01:42:23 tom * (Accent): push QuoteChar on Ungetc stack instead of calling QuotChar * directly (so i-search gets the chance to handle it transparently). * * Revision 14.31 1993/02/13 04:56:48 tom * allow debug options to be specified in "tune.h" cf. "Local.h". * * Revision 14.30 1993/02/05 00:55:21 tom * cleanup whitespace; some random optimizations and debug statements. * * Revision 14.26 1992/08/26 23:56:51 tom * PRIVATE-ized some Variable defs; add RCS directives. * */