examples

Toy examples in single C files.
git clone git://henryandlizzy.uk/examples
Log | Files | Refs

morse.c (4144B)


      1 #include <stdio.h>
      2 #include <ctype.h>
      3 #include <stdlib.h>
      4 
      5 #include <stdio.h>
      6 
      7 enum
      8 {
      9 	START,
     10 	BAD,
     11 	TTTT,
     12 	TTTE,
     13 	EETT,
     14 	ETET,
     15 	EETTE,
     16 	TTEET,
     17 	TETET,
     18 	ETEET,
     19 	ETTET,
     20 	EEETE,
     21 	EEETEE,
     22 };
     23 
     24 struct node
     25 {
     26 	unsigned char seq, dit, dah;
     27 } const nodes[] =
     28 {
     29 	[START] = {0,	'E', 'T'},
     30 	[BAD] = {0,	BAD, BAD},
     31 
     32 	[TETET] = {0,	';', '!'},
     33 	[TTEET] = {0,	BAD, ','},
     34 	[TTTE] = {0,	'8', BAD},
     35 	[TTTT] = {0,	'9', '0'},
     36 	[EEETE] = {0,	EEETEE, BAD},
     37 	[EEETEE] = {0,	BAD, '$'},
     38 	[EETT] = {0,	EETTE, '2'},
     39 	[EETTE] = {0,	'?', '_'},
     40 	[ETEET] = {0,	'"', BAD},
     41 	[ETET] = {0,	'+', BAD},
     42 	[ETTET] = {0,	'@', BAD},
     43 
     44 	['$'] = {0b10110111,	BAD, BAD},
     45 	['!'] = {0b1001010,	BAD, BAD},
     46 	[','] = {0b1001100,	BAD, BAD},
     47 	[')'] = {0b1010010,	BAD, BAD},
     48 	['_'] = {0b1010011,	BAD, BAD},
     49 	['.'] = {0b1010101,	BAD, BAD},
     50 	['='] = {0b101110,	BAD, BAD},
     51 	['-'] = {0b1011110,	BAD, BAD},
     52 	['\''] = {0b1100001,	BAD, BAD},
     53 	['('] = {0b110010,	BAD, ')'},
     54 	['@'] = {0b1101001,	BAD, BAD},
     55 	[';'] = {0b1101010,	BAD, BAD},
     56 	['+'] = {0b110101,	BAD, '.'},
     57 	['"'] = {0b1101101,	BAD, BAD},
     58 	['/'] = {0b110110,	BAD, BAD},
     59 	['?'] = {0b1110011,	BAD, BAD},
     60 	[':'] = {0b1111000,	BAD, BAD},
     61 	['&'] = {0b111101,	BAD, BAD},
     62 	['0'] = {0b100000,	BAD, BAD},
     63 
     64 	['1'] = {0b100001,	'\'', BAD},
     65 	['2'] = {0b100011,	BAD, BAD},
     66 	['3'] = {0b100111,	BAD, BAD},
     67 	['4'] = {0b101111,	BAD, BAD},
     68 	['5'] = {0b111111,	BAD, BAD},
     69 	['6'] = {0b111110,	BAD, '-'},
     70 	['7'] = {0b111100,	BAD, BAD},
     71 	['8'] = {0b111000,	':', BAD},
     72 	['9'] = {0b110000,	BAD, BAD},
     73 
     74 	['A'] = {0b101,	'R', 'W'},
     75 	['B'] = {0b11110,	'6', '='},
     76 	['C'] = {0b11010,	BAD, TETET},
     77 	['D'] = {0b1110,	'B', 'X'},
     78 	['E'] = {0b11,	'I', 'A'},
     79 	['F'] = {0b11011,	BAD, BAD},
     80 	['G'] = {0b1100,	'Z', 'Q'},
     81 	['H'] = {0b11111,	'5', '4'},
     82 	['I'] = {0b111,	'S', 'U'},
     83 	['J'] = {0b10001,	BAD, '1'},
     84 	['K'] = {0b1010,	'C', 'Y'},
     85 	['L'] = {0b11101,	'&', ETEET},
     86 	['M'] = {0b100,	'G', 'O'},
     87 	['N'] = {0b110,	'D', 'K'},
     88 	['O'] = {0b1000,	TTTE, TTTT},
     89 	['P'] = {0b11001,	BAD, ETTET},
     90 	['Q'] = {0b10100,	BAD, BAD},
     91 	['R'] = {0b1101,	'L', ETET},
     92 	['S'] = {0b1111,	'H', 'V'},
     93 	['T'] = {0b10,	'N', 'M'},
     94 	['U'] = {0b1011,	'F', EETT},
     95 	['V'] = {0b10111,	EEETE, '3'},
     96 	['W'] = {0b1001,	'P', 'J'},
     97 	['X'] = {0b10110,	'/', BAD},
     98 	['Y'] = {0b10010,	'(', BAD},
     99 	['Z'] = {0b11100,	'7', TTEET},
    100 
    101 //	[1] = 0b101010,
    102 //	[2] = 0b101010,
    103 //	[3] = 0b1010111,
    104 //	[4] = 0b1010111,
    105 //	[6] = 0b110111,
    106 };
    107 
    108 static char need_space;
    109 
    110 void put_morse_char(unsigned dit)
    111 {
    112 	putchar(dit ? '.' : '_');
    113 }
    114 
    115 void put_morse_seq(unsigned seq)
    116 {
    117 	if (need_space)
    118 		putchar(' ');
    119 	while (seq > 1)
    120 	{
    121 		put_morse_char(seq & 1);
    122 		seq >>= 1;
    123 	}
    124 	need_space = 1;
    125 }
    126 
    127 void put_morse(unsigned char c)
    128 {
    129 	switch (c)
    130 	{
    131 	case ' ':
    132 		if (need_space)
    133 			putchar(c);
    134 		/*fallthrough*/
    135 	case '\n':
    136 		putchar(c);
    137 		need_space = 0;
    138 		break;
    139 	default:
    140 		unsigned char m = nodes[c].seq;
    141 		if (m)
    142 			put_morse_seq(m);
    143 	}
    144 }
    145 
    146 #define ARRAY_SIZE(a)  (sizeof(a) / sizeof(*a))
    147 
    148 void encode()
    149 {
    150 	for (;;)
    151 	{
    152 		int c = getchar();
    153 		if (c == EOF)
    154 			break;
    155 
    156 		c = toupper(c);
    157 		if (c < (int)ARRAY_SIZE(nodes))
    158 			put_morse(c);
    159 	}
    160 }
    161 
    162 void resolve(unsigned char c, int lower)
    163 {
    164 	if (!nodes[c].seq)
    165 		return;
    166 	if (lower)
    167 		putchar(tolower(c));
    168 	else
    169 		putchar(c);
    170 }
    171 
    172 void decode(int lower)
    173 {
    174 	unsigned char out = START;
    175 	for (;;)
    176 	{
    177 		int in = getchar();
    178 		switch (in)
    179 		{
    180 		case ' ':
    181 			resolve(out, lower);
    182 			if (out == START)
    183 				putchar(' ');
    184 			out = START;
    185 			continue;
    186 		case '\n':
    187 			resolve(out, lower);
    188 			out = START;
    189 			putchar('\n');
    190 			continue;
    191 		case '.':
    192 			out = nodes[out].dit;
    193 			continue;
    194 		case '_':
    195 		case '-':
    196 			out = nodes[out].dah;
    197 			continue;
    198 		case EOF:
    199 			resolve(out, lower);
    200 			return;
    201 		default:
    202 			resolve(out, lower);
    203 			out = START;
    204 			continue;
    205 		}
    206 	}
    207 }
    208 
    209 void usage(int code)
    210 {
    211 	fputs("Usage: morse [ e | d | D ]\n\n"
    212 		"  e - encode ASCII to morse code\n"
    213 		"  d - decode morse code to lowercase ASCII\n"
    214 		"  D - decode morse code to uppercase ASCII\n", stderr);
    215 	exit(code);
    216 }
    217 
    218 int main(int argc, char* argv[])
    219 {
    220 	if (argc != 2)
    221 		usage(1);
    222 
    223 	char arg = argv[1][0];
    224 
    225 	switch (arg)
    226 	{
    227 	case 'e':
    228 		encode();
    229 		break;
    230 	case 'd':
    231 	case 'D':
    232 		decode(islower(arg));
    233 		break;
    234 	default:
    235 		usage(1);
    236 	}
    237 }