From 57c6d8064aed35012808019e26aa434ac0b7ffaf Mon Sep 17 00:00:00 2001
From: magnum <magnum>
Date: Tue, 16 Aug 2011 10:05:35 +0200
Subject: [PATCH 15/16] Add best-effort vowel matching to cmpt_cp.pl and JtR

---
 run/cmpt_cp.pl      |   38 +++++++++++++++++++++++++++++++++++---
 src/encoding_data.h |   35 +++++++++++++++++++++++++++++++++++
 src/rules.c         |   28 ++++++++++++++++++++++++++--
 3 files changed, 96 insertions(+), 5 deletions(-)

diff --git a/run/cmpt_cp.pl b/run/cmpt_cp.pl
index f5d077e..61dce2f 100755
--- a/run/cmpt_cp.pl
+++ b/run/cmpt_cp.pl
@@ -2,6 +2,8 @@
 use strict;
 use Encode;
 use Switch;
+use Unicode::Normalize;
+use utf8;  # This source file must be stored UTF-8 encoded
 
 ###############################################################################
 # code page data builder, by magnum / JimF.   v1.2
@@ -44,8 +46,8 @@ sub lookupCategory {
 }
 
 my $to_unicode_high128="";
-my $lower="";  my $upper="";  my $lowonly="";  my $uponly="";  my $specials = "";  my $punctuation = "";  my $alpha = "";  my $digits = "";  my $control = "";  my $invalid = ""; my $whitespace = "";
-my $clower=""; my $cupper=""; my $clowonly=""; my $cuponly=""; my $cspecials = ""; my $cpunctuation = ""; my $calpha = ""; my $cdigits = "";
+my $lower="";  my $upper="";  my $lowonly="";  my $uponly="";  my $specials = "";  my $punctuation = "";  my $alpha = "";  my $digits = "";  my $control = "";  my $invalid = ""; my $whitespace = ""; my $vowels = ""; my $consonants = "";
+my $clower=""; my $cupper=""; my $clowonly=""; my $cuponly=""; my $cspecials = ""; my $cpunctuation = ""; my $calpha = ""; my $cdigits = ""; my $cvowels = ""; my $cconsonants = "";
 my $encu = uc($enc);my $hs = "";
 $encu =~ s/-/_/g;
 #######################################
@@ -119,7 +121,25 @@ foreach my $i (0x80..0xFF) {
 		my $cat = lookupCategory(ord($c));
 		switch ($cat) {
 			case /^Cf/ { $specials .= sprintf("\\x%02X", $i); $cspecials .= $c }
-			case /^L[lotu]/ { $alpha .= sprintf("\\x%02X", $i); $calpha .= $c }
+			case /^L[lotu]/ {
+				$alpha .= sprintf("\\x%02X", $i);
+				$calpha .= $c;
+
+				# best-effort vowel/consonant matching
+				# Note eg. in English, y and w CAN be vowels depending on
+				# situation (boy, yet, we)
+
+				# We normalize to decomposed and match known vowels in lc
+				my $nfd = substr(NFD($c), 0, 1);
+				# Done: Latin, Nordic, Greek, Russian, Ukrainian, Turkish
+				if ($nfd =~ m/[aoueiœæøɪʏɛɔαεηιοωυаэыуояеюиєіı]/i) {
+					$vowels .= sprintf("\\x%02X", $i);
+					$cvowels .= $c;
+				} else {
+					$consonants .= sprintf("\\x%02X", $i);
+					$cconsonants .= $c;
+				}
+			}
 			case /^Lm/ { $specials .= sprintf("\\x%02X", $i); $cspecials .= $c }
 			#case /^Ll/ { $lower .= sprintf("\\x%02X", $i); }
 			#case /^L[tu]/ { $upper .= sprintf("\\x%02X", $i); }
@@ -193,6 +213,18 @@ if (length($control)>80) {print"\\\n\t";}
 if (length($control)>0)  {print "\"".$control."\"";}
 print "\n";
 
+print "\n// $cvowels\n" if $verbose;
+print "#define CHARS_VOWELS_".$encu." ";
+if (length($vowels)>80) {print"\\\n\t";}
+if (length($vowels)>0)  {print "\"".$vowels."\"";}
+print "\n";
+
+print "\n// $cconsonants\n" if $verbose;
+print "#define CHARS_CONSONANTS_".$encu." ";
+if (length($consonants)>80) {print"\\\n\t";}
+if (length($consonants)>0)  {print "\"".$consonants."\"";}
+print "\n";
+
 print "\n" if $verbose;
 print "#define CHARS_INVALID_".$encu." ";
 if (length($invalid)>80) {print"\\\n\t";}
diff --git a/src/encoding_data.h b/src/encoding_data.h
index b30fd7d..3de5608 100644
--- a/src/encoding_data.h
+++ b/src/encoding_data.h
@@ -56,6 +56,9 @@ static UTF16 ISO_8859_1_to_unicode_high128[] = {
 #define CHARS_CONTROL_ISO_8859_1 \
 	"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
 #define CHARS_INVALID_ISO_8859_1 ""
+#define CHARS_VOWELS_ISO_8859_1 \
+	"\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC"
+#define CHARS_CONSONANTS_ISO_8859_1 "\xAA\xB5\xBA\xC7\xD0\xD1\xDD\xDE\xDF\xE7\xF0\xF1\xFD\xFE\xFF"
 
 // here is the KOI8_R to Unicode conversion for KOI8_R characters from 0x80 to 0xFF
 static UTF16 KOI8_R_to_unicode_high128[] = {
@@ -82,6 +85,10 @@ static UTF16 KOI8_R_to_unicode_high128[] = {
 #define CHARS_WHITESPACE_KOI8_R "\x9A"
 #define CHARS_CONTROL_KOI8_R
 #define CHARS_INVALID_KOI8_R ""
+#define CHARS_VOWELS_KOI8_R \
+	"\xA3\xB3\xC0\xC1\xC5\xC9\xCA\xCF\xD1\xD5\xD9\xDC\xE0\xE1\xE5\xE9\xEA\xEF\xF1\xF5\xF9\xFC"
+#define CHARS_CONSONANTS_KOI8_R \
+	"\xC2\xC3\xC4\xC6\xC7\xC8\xCB\xCC\xCD\xCE\xD0\xD2\xD3\xD4\xD6\xD7\xD8\xDA\xDB\xDD\xDE\xDF\xE2\xE3\xE4\xE6\xE7\xE8\xEB\xEC\xED\xEE\xF0\xF2\xF3\xF4\xF6\xF7\xF8\xFA\xFB\xFD\xFE\xFF"
 
 // here is the CP1251 to Unicode conversion for CP1251 characters from 0xA0 to 0xFF 
 static UTF16 CP1251_to_unicode_high128[] = {
@@ -107,6 +114,10 @@ static UTF16 CP1251_to_unicode_high128[] = {
 #define CHARS_WHITESPACE_CP1251 "\xA0"
 #define CHARS_CONTROL_CP1251
 #define CHARS_INVALID_CP1251 "\x98"
+#define CHARS_VOWELS_CP1251 \
+	"\xA1\xA2\xA8\xAA\xAF\xB2\xB3\xB8\xBA\xBF\xC0\xC5\xC8\xC9\xCE\xD3\xDB\xDD\xDE\xDF\xE0\xE5\xE8\xE9\xEE\xF3\xFB\xFD\xFE\xFF"
+#define CHARS_CONSONANTS_CP1251 \
+	"\x80\x81\x83\x8A\x8C\x8D\x8E\x8F\x90\x9A\x9C\x9D\x9E\x9F\xA3\xA5\xB4\xB5\xBC\xBD\xBE\xC1\xC2\xC3\xC4\xC6\xC7\xCA\xCB\xCC\xCD\xCF\xD0\xD1\xD2\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDC\xE1\xE2\xE3\xE4\xE6\xE7\xEA\xEB\xEC\xED\xEF\xF0\xF1\xF2\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFC"
 
 // here is the CP866 to Unicode conversion for CP866 characters from 0xA0 to 0xFF
 static UTF16 CP866_to_unicode_high128[] = {
@@ -133,6 +144,10 @@ static UTF16 CP866_to_unicode_high128[] = {
 #define CHARS_WHITESPACE_CP866 "\xFF"
 #define CHARS_CONTROL_CP866
 #define CHARS_INVALID_CP866 ""
+#define CHARS_VOWELS_CP866 \
+	"\x80\x85\x88\x89\x8E\x93\x9B\x9D\x9E\x9F\xA0\xA5\xA8\xA9\xAE\xE3\xEB\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7"
+#define CHARS_CONSONANTS_CP866 \
+	"\x81\x82\x83\x84\x86\x87\x8A\x8B\x8C\x8D\x8F\x90\x91\x92\x94\x95\x96\x97\x98\x99\x9A\x9C\xA1\xA2\xA3\xA4\xA6\xA7\xAA\xAB\xAC\xAD\xAF\xE0\xE1\xE2\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEC"
 
 // here is the CP1252 to Unicode conversion for CP1252 characters from 0xA0 to 0xFF
 static UTF16 CP1252_to_unicode_high128[] = {
@@ -160,6 +175,10 @@ static UTF16 CP1252_to_unicode_high128[] = {
 #define CHARS_WHITESPACE_CP1252 "\xA0"
 #define CHARS_CONTROL_CP1252
 #define CHARS_INVALID_CP1252 "\x81\x8D\x8F\x90\x9D"
+#define CHARS_VOWELS_CP1252 \
+	"\x8C\x9C\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC"
+#define CHARS_CONSONANTS_CP1252 \
+	"\x83\x8A\x8E\x9A\x9E\x9F\xAA\xB5\xBA\xC7\xD0\xD1\xDD\xDE\xDF\xE7\xF0\xF1\xFD\xFE\xFF"
 
 // here is the ISO_8859_15 to Unicode conversion for ISO_8859_15 characters from 0xA0 to 0xFF
 static UTF16 ISO_8859_15_to_unicode_high128[] = {
@@ -187,6 +206,9 @@ static UTF16 ISO_8859_15_to_unicode_high128[] = {
 #define CHARS_CONTROL_ISO_8859_15 \
 	"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F"
 #define CHARS_INVALID_ISO_8859_15 ""
+#define CHARS_VOWELS_ISO_8859_15 \
+	"\xBC\xBD\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC"
+#define CHARS_CONSONANTS_ISO_8859_15 "\xA6\xA8\xAA\xB4\xB5\xB8\xBA\xBE\xC7\xD0\xD1\xDD\xDE\xDF\xE7\xF0\xF1\xFD\xFE\xFF"
 
 // here is the CP437 to Unicode conversion for CP437 characters from 0xA0 to 0xFF
 static UTF16 CP437_to_unicode_high128[] = {
@@ -213,6 +235,9 @@ static UTF16 CP437_to_unicode_high128[] = {
 #define CHARS_WHITESPACE_CP437 "\xFF"
 #define CHARS_CONTROL_CP437
 #define CHARS_INVALID_CP437 ""
+#define CHARS_VOWELS_CP437 \
+	"\x81\x82\x83\x84\x85\x86\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x99\x9A\xA0\xA1\xA2\xA3\xE0\xEA\xEE"
+#define CHARS_CONSONANTS_CP437 "\x80\x87\x98\x9F\xA4\xA5\xA6\xA7\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEB\xED"
 
 // here is the CP850 to Unicode conversion for CP850 characters from 0xA0 to 0xFF
 static UTF16 CP850_to_unicode_high128[] = {
@@ -241,6 +266,9 @@ static UTF16 CP850_to_unicode_high128[] = {
 #define CHARS_WHITESPACE_CP850 "\xFF"
 #define CHARS_CONTROL_CP850
 #define CHARS_INVALID_CP850 ""
+#define CHARS_VOWELS_CP850 \
+	"\x81\x82\x83\x84\x85\x86\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x99\x9A\x9B\x9D\xA0\xA1\xA2\xA3\xB5\xB6\xB7\xC6\xC7\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xDE\xE0\xE2\xE3\xE4\xE5\xE9\xEA\xEB"
+#define CHARS_CONSONANTS_CP850 "\x80\x87\x98\x9F\xA4\xA5\xA6\xA7\xD0\xD1\xE1\xE6\xE7\xE8\xEC\xED"
 
 // here is the CP858 to Unicode conversion for CP858 characters from 0xA0 to 0xFF
 static UTF16 CP858_to_unicode_high128[] = {
@@ -268,6 +296,9 @@ static UTF16 CP858_to_unicode_high128[] = {
 #define CHARS_WHITESPACE_CP858 "\xFF"
 #define CHARS_CONTROL_CP858
 #define CHARS_INVALID_CP858 ""
+#define CHARS_VOWELS_CP858 \
+	"\x81\x82\x83\x84\x85\x86\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x99\x9A\x9B\x9D\xA0\xA1\xA2\xA3\xB5\xB6\xB7\xC6\xC7\xD2\xD3\xD4\xD6\xD7\xD8\xDE\xE0\xE2\xE3\xE4\xE5\xE9\xEA\xEB"
+#define CHARS_CONSONANTS_CP858 "\x80\x87\x98\x9F\xA4\xA5\xA6\xA7\xD0\xD1\xE1\xE6\xE7\xE8\xEC\xED"
 
 // here is the CP737 to Unicode conversion for CP737 characters from 0xA0 to 0xFF
 static UTF16 CP737_to_unicode_high128[] = {
@@ -294,5 +325,9 @@ static UTF16 CP737_to_unicode_high128[] = {
 #define CHARS_WHITESPACE_CP737 "\xFF"
 #define CHARS_CONTROL_CP737
 #define CHARS_INVALID_CP737 ""
+#define CHARS_VOWELS_CP737 \
+	"\x80\x84\x86\x88\x8E\x93\x97\x98\x9C\x9E\xA0\xA6\xAC\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF4\xF5"
+#define CHARS_CONSONANTS_CP737 \
+	"\x81\x82\x83\x85\x87\x89\x8A\x8B\x8C\x8D\x8F\x90\x91\x92\x94\x95\x96\x99\x9A\x9B\x9D\x9F\xA1\xA2\xA3\xA4\xA5\xA7\xA8\xA9\xAA\xAB\xAD\xAE\xAF"
 
 #endif // __ENCODING_DATA_H__
diff --git a/src/rules.c b/src/rules.c
index 63a620f..62c0d64 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -92,6 +92,10 @@ static struct {
 	"``1234567890-=qqwertyuiop[aasdfghjkl;zzxcvbnm,." \
 	"~~!@#$%^&*()_+QQWERTYUIOP{AASDFGHJKL:ZZXCVBNM<>"
 
+#define CHARS_VOWELS \
+	"aeiouAEIOU"
+#define CHARS_CONSONANTS \
+	"bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ"
 #define CHARS_LOWER \
 	"abcdefghijklmnopqrstuvwxyz"
 #define CHARS_UPPER \
@@ -284,8 +288,6 @@ static void rules_init_classes(void)
 	eightbitchars[128] = 0;
 
 	rules_init_class('?', "?");
-	rules_init_class('v', "aeiouAEIOU");
-	rules_init_class('c', "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ");
 	rules_init_class('b', (char *)&eightbitchars);
 	rules_init_class('Z', "");
 
@@ -306,6 +308,8 @@ static void rules_init_classes(void)
 	}
 
 	if (options.iso8859_1) {
+		rules_init_class('v', CHARS_VOWELS CHARS_VOWELS_ISO_8859_1);
+		rules_init_class('c', CHARS_CONSONANTS CHARS_CONSONANTS_ISO_8859_1);
 		rules_init_class('w', CHARS_WHITESPACE CHARS_WHITESPACE_ISO_8859_1);
 		rules_init_class('p', CHARS_PUNCTUATION CHARS_PUNCTUATION_ISO_8859_1);
 		rules_init_class('s', CHARS_SPECIALS CHARS_SPECIALS_ISO_8859_1);
@@ -317,6 +321,8 @@ static void rules_init_classes(void)
 		rules_init_class('o', CHARS_CONTROL_ASCII CHARS_CONTROL_ISO_8859_1);
 		rules_init_class('Y', CHARS_INVALID_ISO_8859_1);
 	} else if (options.koi8_r) {
+		rules_init_class('v', CHARS_VOWELS CHARS_VOWELS_KOI8_R);
+		rules_init_class('c', CHARS_CONSONANTS CHARS_CONSONANTS_KOI8_R);
 		rules_init_class('w', CHARS_WHITESPACE CHARS_WHITESPACE_KOI8_R);
 		rules_init_class('p', CHARS_PUNCTUATION CHARS_PUNCTUATION_KOI8_R);
 		rules_init_class('s', CHARS_SPECIALS CHARS_SPECIALS_KOI8_R);
@@ -328,6 +334,8 @@ static void rules_init_classes(void)
 		rules_init_class('o', CHARS_CONTROL_ASCII CHARS_CONTROL_KOI8_R);
 		rules_init_class('Y', CHARS_INVALID_KOI8_R);
 	} else if (options.cp1251) {
+		rules_init_class('v', CHARS_VOWELS CHARS_VOWELS_CP1251);
+		rules_init_class('c', CHARS_CONSONANTS CHARS_CONSONANTS_CP1251);
 		rules_init_class('w', CHARS_WHITESPACE CHARS_WHITESPACE_CP1251);
 		rules_init_class('p', CHARS_PUNCTUATION CHARS_PUNCTUATION_CP1251);
 		rules_init_class('s', CHARS_SPECIALS CHARS_SPECIALS_CP1251);
@@ -339,6 +347,8 @@ static void rules_init_classes(void)
 		rules_init_class('o', CHARS_CONTROL_ASCII CHARS_CONTROL_CP1251);
 		rules_init_class('Y', CHARS_INVALID_CP1251);
 	} else if (options.cp866) {
+		rules_init_class('v', CHARS_VOWELS CHARS_VOWELS_CP866);
+		rules_init_class('c', CHARS_CONSONANTS CHARS_CONSONANTS_CP866);
 		rules_init_class('w', CHARS_WHITESPACE CHARS_WHITESPACE_CP866);
 		rules_init_class('p', CHARS_PUNCTUATION CHARS_PUNCTUATION_CP866);
 		rules_init_class('s', CHARS_SPECIALS CHARS_SPECIALS_CP866);
@@ -350,6 +360,8 @@ static void rules_init_classes(void)
 		rules_init_class('o', CHARS_CONTROL_ASCII CHARS_CONTROL_CP866);
 		rules_init_class('Y', CHARS_INVALID_CP866);
 	} else if (options.cp1252) {
+		rules_init_class('v', CHARS_VOWELS CHARS_VOWELS_CP1252);
+		rules_init_class('c', CHARS_CONSONANTS CHARS_CONSONANTS_CP1252);
 		rules_init_class('w', CHARS_WHITESPACE CHARS_WHITESPACE_CP1252);
 		rules_init_class('p', CHARS_PUNCTUATION CHARS_PUNCTUATION_CP1252);
 		rules_init_class('s', CHARS_SPECIALS CHARS_SPECIALS_CP1252);
@@ -361,6 +373,8 @@ static void rules_init_classes(void)
 		rules_init_class('o', CHARS_CONTROL_ASCII CHARS_CONTROL_CP1252);
 		rules_init_class('Y', CHARS_INVALID_CP1252);
 	} else if (options.iso8859_15) {
+		rules_init_class('v', CHARS_VOWELS CHARS_VOWELS_ISO_8859_15);
+		rules_init_class('c', CHARS_CONSONANTS CHARS_CONSONANTS_ISO_8859_15);
 		rules_init_class('w', CHARS_WHITESPACE CHARS_WHITESPACE_ISO_8859_15);
 		rules_init_class('p', CHARS_PUNCTUATION CHARS_PUNCTUATION_ISO_8859_15);
 		rules_init_class('s', CHARS_SPECIALS CHARS_SPECIALS_ISO_8859_15);
@@ -372,6 +386,8 @@ static void rules_init_classes(void)
 		rules_init_class('o', CHARS_CONTROL_ASCII CHARS_CONTROL_ISO_8859_15);
 		rules_init_class('Y', CHARS_INVALID_ISO_8859_15);
 	} else if (options.cp437) {
+		rules_init_class('v', CHARS_VOWELS CHARS_VOWELS_CP437);
+		rules_init_class('c', CHARS_CONSONANTS CHARS_CONSONANTS_CP437);
 		rules_init_class('w', CHARS_WHITESPACE CHARS_WHITESPACE_CP437);
 		rules_init_class('p', CHARS_PUNCTUATION CHARS_PUNCTUATION_CP437);
 		rules_init_class('s', CHARS_SPECIALS CHARS_SPECIALS_CP437);
@@ -384,6 +400,8 @@ static void rules_init_classes(void)
 		rules_init_class('Y', CHARS_INVALID_CP437);
 	} else if (options.cp850) {
 		// NOTE, we need to deal with U+0131 (dottless I)
+		rules_init_class('v', CHARS_VOWELS CHARS_VOWELS_CP850);
+		rules_init_class('c', CHARS_CONSONANTS CHARS_CONSONANTS_CP850);
 		rules_init_class('w', CHARS_WHITESPACE CHARS_WHITESPACE_CP850);
 		rules_init_class('p', CHARS_PUNCTUATION CHARS_PUNCTUATION_CP850);
 		rules_init_class('s', CHARS_SPECIALS CHARS_SPECIALS_CP850);
@@ -395,6 +413,8 @@ static void rules_init_classes(void)
 		rules_init_class('o', CHARS_CONTROL_ASCII CHARS_CONTROL_CP850);
 		rules_init_class('Y', CHARS_INVALID_CP850);
 	} else if (options.cp858) {
+		rules_init_class('v', CHARS_VOWELS CHARS_VOWELS_CP858);
+		rules_init_class('c', CHARS_CONSONANTS CHARS_CONSONANTS_CP858);
 		rules_init_class('w', CHARS_WHITESPACE CHARS_WHITESPACE_CP858);
 		rules_init_class('p', CHARS_PUNCTUATION CHARS_PUNCTUATION_CP858);
 		rules_init_class('s', CHARS_SPECIALS CHARS_SPECIALS_CP858);
@@ -406,6 +426,8 @@ static void rules_init_classes(void)
 		rules_init_class('o', CHARS_CONTROL_ASCII CHARS_CONTROL_CP858);
 		rules_init_class('Y', CHARS_INVALID_CP858);
 	} else if (options.cp737) {
+		rules_init_class('v', CHARS_VOWELS CHARS_VOWELS_CP737);
+		rules_init_class('c', CHARS_CONSONANTS CHARS_CONSONANTS_CP737);
 		rules_init_class('w', CHARS_WHITESPACE CHARS_WHITESPACE_CP737);
 		rules_init_class('p', CHARS_PUNCTUATION CHARS_PUNCTUATION_CP737);
 		rules_init_class('s', CHARS_SPECIALS CHARS_SPECIALS_CP737);
@@ -417,6 +439,8 @@ static void rules_init_classes(void)
 		rules_init_class('o', CHARS_CONTROL_ASCII CHARS_CONTROL_CP737);
 		rules_init_class('Y', CHARS_INVALID_CP737);
 	} else {
+		rules_init_class('v', CHARS_VOWELS);
+		rules_init_class('c', CHARS_CONSONANTS);
 		rules_init_class('w', CHARS_WHITESPACE);
 		rules_init_class('p', CHARS_PUNCTUATION);
 		rules_init_class('s', CHARS_SPECIALS);
-- 
1.7.4.1

