1 | #include <stdint.h>
|
2 | #include <stddef.h>
|
3 | #include <stdio.h>
|
4 |
|
5 | typedef uint8_t morse_symbol_t;
|
6 |
|
7 | #define MORSE_MAPPING \
|
8 | X('A', 0x06) X('B', 0x11) X('C', 0x15) X('D', 0x09) \
|
9 | X('E', 0x02) X('F', 0x14) X('G', 0x0B) X('H', 0x10) \
|
10 | X('I', 0x04) X('J', 0x1E) X('K', 0x0D) X('L', 0x12) \
|
11 | X('M', 0x07) X('N', 0x05) X('O', 0x0F) X('P', 0x16) \
|
12 | X('Q', 0x1B) X('R', 0x0A) X('S', 0x08) X('T', 0x03) \
|
13 | X('U', 0x0C) X('V', 0x18) X('W', 0x0E) X('X', 0x19) \
|
14 | X('Y', 0x1D) X('Z', 0x13) X('1', 0x3E) X('2', 0x3C) \
|
15 | X('3', 0x38) X('4', 0x30) X('5', 0x20) X('6', 0x21) \
|
16 | X('7', 0x23) X('8', 0x27) X('9', 0x2F) X('0', 0x3F) \
|
17 | X(' ', 0x01) X('.', 0x6A) X(',', 0x73) X(':', 0x47) \
|
18 | X(';', 0x55) X('?', 0x4C) X('!', 0x75) X('-', 0x61) \
|
19 | X('_', 0x6C) X('(', 0x2D) X(')', 0x6D) X('\'', 0x5E) \
|
20 | X('=', 0x31) X('+', 0x2A) X('/', 0x29) X('@', 0x56)
|
21 |
|
22 | #define X(C, M) [C] = M,
|
23 | morse_symbol_t char_morse_map[] = {
|
24 | MORSE_MAPPING
|
25 | X('a', 0x06) X('b', 0x11) X('c', 0x15) X('d', 0x09)
|
26 | X('e', 0x02) X('f', 0x14) X('g', 0x0B) X('h', 0x10)
|
27 | X('i', 0x04) X('j', 0x1E) X('k', 0x0D) X('l', 0x12)
|
28 | X('m', 0x07) X('n', 0x05) X('o', 0x0F) X('p', 0x16)
|
29 | X('q', 0x1B) X('r', 0x0A) X('s', 0x08) X('t', 0x03)
|
30 | X('u', 0x0C) X('v', 0x18) X('w', 0x0E) X('x', 0x19)
|
31 | X('y', 0x1D) X('z', 0x13)
|
32 | };
|
33 | #undef X
|
34 | const size_t char_morse_map_count = sizeof(char_morse_map) / sizeof(*char_morse_map);
|
35 |
|
36 | #define X(C, M) [M] = C,
|
37 | char morse_char_map[] = {MORSE_MAPPING};
|
38 | #undef X
|
39 | const size_t morse_char_map_count = sizeof(morse_char_map) / sizeof(*morse_char_map);
|
40 |
|
41 | #undef MORSE_MAPPING
|
42 |
|
43 | typedef char morse_symbol_sequence_t[8];
|
44 |
|
45 | unsigned morse_symbol_sequence_unpack(morse_symbol_sequence_t ret, morse_symbol_t symbol){
|
46 | if(symbol == 1){ // 5 di pause and the prev+this symbol end di pause, makes a 7 di pause overall
|
47 | ret[0] = ' ';
|
48 | ret[1] = ' ';
|
49 | ret[2] = ' ';
|
50 | ret[3] = ' ';
|
51 | ret[4] = ' ';
|
52 | ret[5] = '\0';
|
53 | return 6;
|
54 | }
|
55 | unsigned i=0;
|
56 | while(symbol > 1){
|
57 | ret[i++] = ".-"[symbol%2];
|
58 | symbol /= 2;
|
59 | }
|
60 | ret[i] = '\0';
|
61 | return i;
|
62 | }
|
63 |
|
64 | morse_symbol_t morse_symbol_sequence_pack(const morse_symbol_sequence_t seq){
|
65 | if(seq[0]==' ' && seq[1]==' ' && seq[2]==' ' && seq[3]==' ' && seq[4]==' ' && seq[5]=='\0')
|
66 | return 0x1;
|
67 | morse_symbol_t res = 1;
|
68 | for(unsigned i; seq[i]; i++){
|
69 | char x = seq[i];
|
70 | res *= 2;
|
71 | if(x == '-'){
|
72 | res += 1;
|
73 | }else if(x != '.')
|
74 | return 0;
|
75 | }
|
76 | return res;
|
77 | }
|
78 |
|
79 | morse_symbol_t morse_lookup_char(char c){
|
80 | unsigned char uc = c;
|
81 | if(uc >= char_morse_map_count)
|
82 | return 0;
|
83 | return char_morse_map[uc];
|
84 | }
|
85 |
|
86 | char morse_lookup_symbol(morse_symbol_t s){
|
87 | if(s >= morse_char_map_count)
|
88 | return 0;
|
89 | return morse_char_map[s];
|
90 | }
|
91 |
|
92 | int func_puts(const char* c, int(*putchar)(int c)){
|
93 | if(!c) return -1;
|
94 | while(*c)
|
95 | if(putchar(*(c++)) == EOF)
|
96 | return -1;
|
97 | return 0;
|
98 | }
|
99 |
|
100 | int morse_putchar(int ch){
|
101 | morse_symbol_sequence_t sequence;
|
102 | morse_symbol_t symbol = morse_lookup_char(ch);
|
103 | if(!morse_symbol_sequence_unpack(sequence, symbol))
|
104 | return 0;
|
105 | printf("%s ", sequence);
|
106 | return ch;
|
107 | }
|
108 |
|
109 | int main(){
|
110 | func_puts("Hello World!", putchar);
|
111 | puts("");
|
112 | func_puts("Hello World!", morse_putchar);
|
113 | puts("");
|
114 | return 0;
|
115 | }
|