~netrek-developers/netrek-client-cow/trunk

« back to all changes in this revision

Viewing changes to censor.c

  • Committer: Collin Pruitt
  • Date: 2009-05-12 04:30:09 UTC
  • Revision ID: collinp111@gmail.com-20090512043009-3jsjojoyrk16oass
Initial upload - updated from http://james.tooraweenah.com/darcs/netrek-client-cow/ using darcs (hince the existnace of _darcs), fully patched.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <assert.h>
 
4
#include <string.h>
 
5
#include <ctype.h>
 
6
 
 
7
#define MAX_CURSE_LEN 10
 
8
#define REPLACE_STR_LEN 20
 
9
#define NUM_CURSES 8
 
10
#define NOT_FOUND -1
 
11
 
 
12
typedef struct
 
13
  {
 
14
    char    badWord[MAX_CURSE_LEN];
 
15
    int     beginningOnly;
 
16
    int     skip[128];
 
17
  }
 
18
profanity;
 
19
 
 
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. */
 
24
 
 
25
static profanity curseWords[NUM_CURSES] =
 
26
{
 
27
  {"damn", 0},
 
28
  {"fuck", 0},
 
29
  {"bastard", 0},
 
30
  {"shit", 0},
 
31
  {"bitch", 0},
 
32
  {"twat", 1},
 
33
  {"cunt", 0},
 
34
  {"dammit", 0}
 
35
};
 
36
 
 
37
static char replacementChars[REPLACE_STR_LEN + 1] = "@#$%^&*%#$%@#$*&@%$%";
 
38
 
 
39
/* + 1 for trailing null */
 
40
 
 
41
void    initSkipArray(char *word, int *skip)
 
42
{
 
43
  int     i, wordLen = strlen(word);
 
44
 
 
45
  for (i = 0; i < 128; i++)
 
46
    skip[i] = wordLen;
 
47
  for (i = 0; i < wordLen; i++)
 
48
    {
 
49
      skip[(int) word[i]] = wordLen - i - 1;
 
50
      if (isascii(toupper(word[i])))
 
51
        skip[toupper(word[i])] = skip[(int) word[i]];
 
52
    }
 
53
}
 
54
 
 
55
void    initCensoring()
 
56
{
 
57
  int     i;
 
58
 
 
59
  for (i = 0; i < NUM_CURSES; i++)
 
60
    initSkipArray(curseWords[i].badWord, curseWords[i].skip);
 
61
}
 
62
 
 
63
static int search(char *word, char *text, int *skip)
 
64
{
 
65
  int     i, j, wordLen = strlen(word), textLen = strlen(text);
 
66
 
 
67
  for (i = j = wordLen - 1; j >= 0; i--, j--)
 
68
    while (tolower(text[i]) != word[j])
 
69
      {
 
70
        int     t = skip[(int) text[i]];
 
71
 
 
72
        i += (wordLen - j > t) ? wordLen - j : t;
 
73
        if (i >= textLen)
 
74
          return NOT_FOUND;
 
75
        j = wordLen - 1;
 
76
      }
 
77
  return i + 1;
 
78
}
 
79
 
 
80
char   *censor(char *text)
 
81
{
 
82
  int     i, j, t = strlen(text) - 1;
 
83
  char   *str = text;
 
84
 
 
85
  for (i = 0; i < NUM_CURSES; i++)
 
86
    {
 
87
      text = str;
 
88
      while ((j = search(curseWords[i].badWord, text, curseWords[i].skip))
 
89
             != NOT_FOUND)
 
90
        {
 
91
          int     k, l, wordBegin, wordEnd;
 
92
 
 
93
          for (wordBegin = j; wordBegin > 0; wordBegin--)
 
94
            if (!isalpha(text[wordBegin - 1]))
 
95
              break;
 
96
          for (wordEnd = j + strlen(curseWords[i].badWord) - 1; wordEnd < t; wordEnd++)
 
97
            if (!isalpha(text[wordEnd + 1]))
 
98
              break;
 
99
          if (!curseWords[i].beginningOnly || wordBegin == j)
 
100
            for (k = wordBegin, l = 0; k <= wordEnd; k++)
 
101
              {
 
102
                text[k] = replacementChars[l];
 
103
                if (++l >= REPLACE_STR_LEN)
 
104
                  l = 0;                         /* make sure we don't go *
 
105
                                                  * past bound of *
 
106
                                                  * replacementChars */
 
107
              }
 
108
          text += wordEnd;                       /* so we don't go into *
 
109
                                                  * infinite loop if *
 
110
                                                  * beginningOnly */
 
111
        }
 
112
    }
 
113
  return str;
 
114
}
 
115
 
 
116
#undef MAX_CURSE_LEN
 
117
#undef REPLACE_STR_LEN
 
118
#undef NUM_CURSES
 
119
#undef NOT_FOUND