proquint.c (2057B)
1 #include <u.h> 2 #include <libc.h> 3 #include "proquint.h" 4 5 /* Map uints to consonants. */ 6 static char uint2consonant[] = { 7 'b', 'd', 'f', 'g', 8 'h', 'j', 'k', 'l', 9 'm', 'n', 'p', 'r', 10 's', 't', 'v', 'z' 11 }; 12 13 /* Map uints to vowels. */ 14 static char uint2vowel[] = { 15 'a', 'i', 'o', 'u' 16 }; 17 18 void 19 uint2quint(char *quint /*output*/, u32int i, int sepChar) { 20 /* K&R section 2.9: "Right shifting an unsigned quantity always 21 fills vacated it with zero." */ 22 u32int j; 23 24 # define APPEND(X) *quint = (X); ++quint 25 # define MASK_FIRST4 0xF0000000 26 # define MASK_FIRST2 0xC0000000 27 # define HANDLE_CONSONANT \ 28 j = i & MASK_FIRST4; \ 29 i <<= 4; j >>= 28; \ 30 APPEND(uint2consonant[j]) 31 32 # define HANDLE_VOWEL \ 33 j = i & MASK_FIRST2; \ 34 i <<= 2; j >>= 30; \ 35 APPEND(uint2vowel[j]) 36 37 HANDLE_CONSONANT; 38 HANDLE_VOWEL; 39 HANDLE_CONSONANT; 40 HANDLE_VOWEL; 41 HANDLE_CONSONANT; 42 43 if (sepChar) { 44 APPEND(((char) sepChar)); 45 } 46 47 HANDLE_CONSONANT; 48 HANDLE_VOWEL; 49 HANDLE_CONSONANT; 50 HANDLE_VOWEL; 51 HANDLE_CONSONANT; 52 53 # undef HANDLE_VOWEL 54 # undef HANDLE_CONSONANT 55 # undef APPEND 56 # undef MASK_FIRST2 57 # undef MASK_FIRST4 58 } 59 60 u32int 61 quint2uint(char *quint) { 62 u32int res = 0; 63 char c; 64 for(; (c=*quint); ++quint) { 65 switch(c) { 66 case 'b': res <<= 4; res += 0; break; 67 case 'd': res <<= 4; res += 1; break; 68 case 'f': res <<= 4; res += 2; break; 69 case 'g': res <<= 4; res += 3; break; 70 case 'h': res <<= 4; res += 4; break; 71 case 'j': res <<= 4; res += 5; break; 72 case 'k': res <<= 4; res += 6; break; 73 case 'l': res <<= 4; res += 7; break; 74 case 'm': res <<= 4; res += 8; break; 75 case 'n': res <<= 4; res += 9; break; 76 case 'p': res <<= 4; res += 10; break; 77 case 'r': res <<= 4; res += 11; break; 78 case 's': res <<= 4; res += 12; break; 79 case 't': res <<= 4; res += 13; break; 80 case 'v': res <<= 4; res += 14; break; 81 case 'z': res <<= 4; res += 15; break; 82 case 'a': res <<= 2; res += 0; break; 83 case 'i': res <<= 2; res += 1; break; 84 case 'o': res <<= 2; res += 2; break; 85 case 'u': res <<= 2; res += 3; break; 86 default: break; 87 } 88 } 89 return res; 90 }