7
#define MAX_CURSE_LEN 10
8
#define REPLACE_STR_LEN 20
14
char badWord[MAX_CURSE_LEN];
20
/* if beginningOnly is true censor only looks for the curse at the beginning
21
* of words. Currently only set for "twat" so "saltwater", etc aren't caught.
22
* Grepped for the other strings in /usr/dict/words and came up with a blank,
23
* so beginningOnly is left off for them. */
25
static profanity curseWords[NUM_CURSES] =
37
static char replacementChars[REPLACE_STR_LEN + 1] = "@#$%^&*%#$%@#$*&@%$%";
39
/* + 1 for trailing null */
41
void initSkipArray(char *word, int *skip)
43
int i, wordLen = strlen(word);
45
for (i = 0; i < 128; i++)
47
for (i = 0; i < wordLen; i++)
49
skip[(int) word[i]] = wordLen - i - 1;
50
if (isascii(toupper(word[i])))
51
skip[toupper(word[i])] = skip[(int) word[i]];
59
for (i = 0; i < NUM_CURSES; i++)
60
initSkipArray(curseWords[i].badWord, curseWords[i].skip);
63
static int search(char *word, char *text, int *skip)
65
int i, j, wordLen = strlen(word), textLen = strlen(text);
67
for (i = j = wordLen - 1; j >= 0; i--, j--)
68
while (tolower(text[i]) != word[j])
70
int t = skip[(int) text[i]];
72
i += (wordLen - j > t) ? wordLen - j : t;
80
char *censor(char *text)
82
int i, j, t = strlen(text) - 1;
85
for (i = 0; i < NUM_CURSES; i++)
88
while ((j = search(curseWords[i].badWord, text, curseWords[i].skip))
91
int k, l, wordBegin, wordEnd;
93
for (wordBegin = j; wordBegin > 0; wordBegin--)
94
if (!isalpha(text[wordBegin - 1]))
96
for (wordEnd = j + strlen(curseWords[i].badWord) - 1; wordEnd < t; wordEnd++)
97
if (!isalpha(text[wordEnd + 1]))
99
if (!curseWords[i].beginningOnly || wordBegin == j)
100
for (k = wordBegin, l = 0; k <= wordEnd; k++)
102
text[k] = replacementChars[l];
103
if (++l >= REPLACE_STR_LEN)
104
l = 0; /* make sure we don't go *
106
* replacementChars */
108
text += wordEnd; /* so we don't go into *
117
#undef REPLACE_STR_LEN