File: censor.c

package info (click to toggle)
netrek-client-cow 3.3.0-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd, wheezy
  • size: 6,196 kB
  • ctags: 5,158
  • sloc: ansic: 43,111; sh: 2,820; python: 380; makefile: 133; sed: 16
file content (119 lines) | stat: -rw-r--r-- 2,719 bytes parent folder | download | duplicates (5)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <ctype.h>

#define MAX_CURSE_LEN 10
#define REPLACE_STR_LEN 20
#define NUM_CURSES 8
#define NOT_FOUND -1

typedef struct
  {
    char    badWord[MAX_CURSE_LEN];
    int     beginningOnly;
    int     skip[128];
  }
profanity;

/* if beginningOnly is true censor only looks for the curse at the beginning
 * of words.  Currently only set for "twat" so "saltwater", etc aren't caught.
 * Grepped for the other strings in /usr/dict/words and came up with a blank,
 * so beginningOnly is left off for them. */

static profanity curseWords[NUM_CURSES] =
{
  {"damn", 0},
  {"fuck", 0},
  {"bastard", 0},
  {"shit", 0},
  {"bitch", 0},
  {"twat", 1},
  {"cunt", 0},
  {"dammit", 0}
};

static char replacementChars[REPLACE_STR_LEN + 1] = "@#$%^&*%#$%@#$*&@%$%";

/* + 1 for trailing null */

void    initSkipArray(char *word, int *skip)
{
  int     i, wordLen = strlen(word);

  for (i = 0; i < 128; i++)
    skip[i] = wordLen;
  for (i = 0; i < wordLen; i++)
    {
      skip[(int) word[i]] = wordLen - i - 1;
      if (isascii(toupper(word[i])))
	skip[toupper(word[i])] = skip[(int) word[i]];
    }
}

void    initCensoring()
{
  int     i;

  for (i = 0; i < NUM_CURSES; i++)
    initSkipArray(curseWords[i].badWord, curseWords[i].skip);
}

static int search(char *word, char *text, int *skip)
{
  int     i, j, wordLen = strlen(word), textLen = strlen(text);

  for (i = j = wordLen - 1; j >= 0; i--, j--)
    while (tolower(text[i]) != word[j])
      {
	int     t = skip[(int) text[i]];

	i += (wordLen - j > t) ? wordLen - j : t;
	if (i >= textLen)
	  return NOT_FOUND;
	j = wordLen - 1;
      }
  return i + 1;
}

char   *censor(char *text)
{
  int     i, j, t = strlen(text) - 1;
  char   *str = text;

  for (i = 0; i < NUM_CURSES; i++)
    {
      text = str;
      while ((j = search(curseWords[i].badWord, text, curseWords[i].skip))
	     != NOT_FOUND)
	{
	  int     k, l, wordBegin, wordEnd;

	  for (wordBegin = j; wordBegin > 0; wordBegin--)
	    if (!isalpha(text[wordBegin - 1]))
	      break;
	  for (wordEnd = j + strlen(curseWords[i].badWord) - 1; wordEnd < t; wordEnd++)
	    if (!isalpha(text[wordEnd + 1]))
	      break;
	  if (!curseWords[i].beginningOnly || wordBegin == j)
	    for (k = wordBegin, l = 0; k <= wordEnd; k++)
	      {
		text[k] = replacementChars[l];
		if (++l >= REPLACE_STR_LEN)
		  l = 0;			 /* make sure we don't go *
						  * past bound of *
						  * replacementChars */
	      }
	  text += wordEnd;			 /* so we don't go into *
						  * infinite loop if *
						  * beginningOnly */
	}
    }
  return str;
}

#undef MAX_CURSE_LEN
#undef REPLACE_STR_LEN
#undef NUM_CURSES
#undef NOT_FOUND