Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
tree: 076cf4ad5c
Fetching contributors…

Cannot retrieve contributors at this time

343 lines (310 sloc) 9.151 kB
/* digraph.c */
/* Copyright 1995 by Steve Kirkendall */
#include "elvis.h"
#ifdef FEATURE_RCSID
char id_digraph[] = "$Id: digraph.c,v 2.13 2004/03/21 23:24:41 steve Exp $";
#endif
#ifndef NO_DIGRAPH
static void adjustctype P_((_CHAR_ ch));
/* This structure is used to store digraphs. Note that "in1" is always less
* than or equal to "in2".
*/
typedef struct dig_s
{
struct dig_s *next; /* another digraph */
CHAR in1, in2; /* the input characters of this digraph */
CHAR out; /* the character they form */
ELVBOOL save; /* user-defined? */
} DIGRAPH;
/* This is a list of all defined digraphs */
DIGRAPH *digs;
#ifdef NEED_CTYPE
CHAR elvct_upper[256] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
CHAR elvct_lower[256] =
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
#define U ELVCT_UPPER
#define L ELVCT_LOWER
#define XU ELVCT_UPPER|ELVCT_XDIGIT
#define XL ELVCT_LOWER|ELVCT_XDIGIT
#define XD ELVCT_DIGIT|ELVCT_XDIGIT
#define P ELVCT_PUNCT
#define S ELVCT_SPACE
#define C ELVCT_CNTRL
#define SC ELVCT_SPACE|ELVCT_CNTRL
CHAR elvct_class[256] =
{
C, C, C, C, C, C, C, C, C, SC, SC, C, SC, SC, C, C,
C, C, C, C, C, C, C, C, C, C, C, C, C, C, C, C,
S, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
XD, XD, XD, XD, XD, XD, XD, XD, XD, XD, P, P, P, P, P, P,
P, XU, XU, XU, XU, XU, XU, U, U, U, U, U, U, U, U, U,
U, U, U, U, U, U, U, U, U, U, U, P, P, P, P, P,
P, XL, XL, XL, XL, XL, XL, L, L, L, L, L, L, L, L, L,
L, L, L, L, L, L, L, L, L, L, L, P, P, P, P, C,
P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P,
P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P
};
#undef U
#undef L
#undef XU
#undef XL
#undef XD
#undef P
#undef S
#undef C
#undef SC
static void adjustctype(ch)
_CHAR_ ch; /* a digraph character that changed */
{
DIGRAPH *dp; /* the changed digraph, or NULL if deleted */
CHAR tmp;
/* if ASCII, leave it alone */
if (ch < 0x80)
return;
/* try to find a digraph that results in this character */
for (dp = digs; dp && dp->out != ch; dp = dp->next)
{
}
/* what kind of change? */
if (dp && ((elvupper(dp->in1) && !elvlower(dp->in2)) || elvupper(dp->in2)))
{
/* making it uppercase */
setupper(ch);
clrlower(ch);
clrpunct(ch);
tmp = digraph(elvtolower(dp->in1), elvtolower(dp->in2));
if (tmp >= 0x80)
{
/* we can make an uppercase/lowercase pair */
elvtoupper(tmp) = ch;
elvtolower(ch) = tmp;
}
}
else if (dp && ((!elvupper(dp->in1) && elvlower(dp->in2)) || elvlower(dp->in1)))
{
/* making it lowercase */
setlower(ch);
clrupper(ch);
clrpunct(ch);
tmp = digraph(elvtoupper(dp->in1), elvtoupper(dp->in2));
if (tmp >= 0x80)
{
/* we can make an uppercase/lowercase pair */
elvtolower(tmp) = ch;
elvtoupper(ch) = tmp;
}
}
else
{
/* deleting it, or making it punctuation */
if (elvupper(ch))
{
clrupper(ch);
tmp = elvtolower(ch);
elvtolower(ch) = ch;
elvtoupper(tmp) = tmp;
clrupper(ch);
}
else if (elvtolower(ch))
{
clrlower(ch);
tmp = elvtoupper(ch);
elvtoupper(ch) = ch;
elvtolower(tmp) = tmp;
clrlower(ch);
}
setpunct(ch);
}
}
#endif
/* This function looks up a digraph. If it finds the digraph, it returns
* the non-ASCII character; otherwise it returns the second parameter character.
*/
CHAR digraph(in1, in2)
_CHAR_ in1; /* the underlying character */
_CHAR_ in2; /* the second character */
{
CHAR newkey;
DIGRAPH *dp;
/* remember the new key, so we can return it if this isn't a digraph */
newkey = in2;
/* sort in1 and in2, so that their original order won't matter */
if (in1 > in2)
{
in2 = in1;
in1 = newkey;
}
/* scan through the digraph chart */
for (dp = digs;
dp && (dp->in1 != in1 || dp->in2 != in2);
dp = dp->next)
{
}
/* if this combination isn't in there, just use the new key */
if (!dp)
{
return newkey;
}
/* else use the digraph key */
return dp->out;
}
/* This function lists, defines, or deletes digraphs. If passed a NULL
* pointer it will list the user-defined digraphs or all digraphs, depending
* on the value of "bang." If passed a 2-character string, it will delete
* a digraph. If passed a 3-character string, it will define a digraph.
*/
void digaction(win, bang, extra)
WINDOW win; /* window to write to, if listing */
ELVBOOL bang; /* list all, or define non-ASCII */
CHAR *extra; /* NULL to list, "xx" to delete, "xxy" to add */
{
int dig;
DIGRAPH *dp;
DIGRAPH *prev;
CHAR listbuf[8];
/* if no args, then display the existing digraphs */
if (!extra)
{
listbuf[0] = listbuf[1] = listbuf[2] = listbuf[5] = ' ';
listbuf[7] = '\0';
for (dig = 0, dp = digs; dp; dp = dp->next)
{
if (dp->save || bang)
{
dig += 7;
if (dig >= o_columns(win))
{
drawextext(win, toCHAR("\n"), 1);
dig = 7;
}
listbuf[3] = dp->in1;
listbuf[4] = dp->in2;
listbuf[6] = dp->out;
drawextext(win, listbuf, 7);
}
}
drawextext(win, toCHAR("\n"), 1);
return;
}
/* make sure we have at least two characters */
if (!extra[1])
{
msg(MSG_ERROR, "digraphs must be composed of two characters");
return;
}
/* sort in1 and in2, so that their original order won't matter */
if (extra[0] > extra[1])
{
dig = extra[0];
extra[0] = extra[1];
extra[1] = dig;
}
/* locate the new digraph character */
for (dig = 2; extra[dig] == ' ' || extra[dig] == '\t'; dig++)
{
}
dig = extra[dig];
if (!bang && dig)
{
dig |= 0x80;
}
/* search for the digraph */
for (prev = (DIGRAPH *)0, dp = digs;
dp && (dp->in1 != extra[0] || dp->in2 != extra[1]);
prev = dp, dp = dp->next)
{
}
/* deleting the digraph? */
if (!dig)
{
if (!dp)
{
return;
}
if (prev)
prev->next = dp->next;
else
digs = dp->next;
#ifdef NEED_CTYPE
adjustctype(dp->out);
#endif
safefree(dp);
return;
}
/* if necessary, create a new digraph struct for the new digraph */
if (dig && !dp)
{
dp = (DIGRAPH *)safekept(1, sizeof *dp);
if (prev)
prev->next = dp;
else
digs = dp;
dp->next = (DIGRAPH *)0;
}
/* assign it the new digraph value */
dp->in1 = extra[0];
dp->in2 = extra[1];
dp->out = dig;
dp->save = (ELVBOOL)(win != (WINDOW)0);
# ifdef NEED_CTYPE
adjustctype(dig);
# endif
}
# ifdef FEATURE_MKEXRC
void digsave(buf)
BUFFER buf; /* the buffer to append commands onto */
{
static CHAR text[] = "digraph! XX Y\n";
DIGRAPH *dp;
for (dp = digs; dp; dp = dp->next)
{
if (dp->save)
{
text[9] = dp->in1;
text[10] = dp->in2;
text[12] = dp->out;
bufappend(buf, text, QTY(text) - 1);
}
}
}
# endif /* FEATURE_MKEXRC */
#endif
Jump to Line
Something went wrong with that request. Please try again.