From 0cc9b20c15460213e488bf5e70963b941482f628 Mon Sep 17 00:00:00 2001 From: William Harrington Date: Tue, 14 Jan 2025 16:06:02 -0600 Subject: Add source. --- spo256/chars.c | 339 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 spo256/chars.c (limited to 'spo256/chars.c') diff --git a/spo256/chars.c b/spo256/chars.c new file mode 100644 index 0000000..e4b2a2a --- /dev/null +++ b/spo256/chars.c @@ -0,0 +1,339 @@ +/* + * Character state parser for text-to-speech server. + * $Id: chars.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include +#include +#include "speak.h" + +enum +{ + CH_IGNORE, + CH_PERIOD, + CH_QUOTE, + CH_ESCAPE, + CH_SPACE, + CH_ALPHA, + CH_NUMERIC, + CH_PUNCT, +}; + +static uchar map[256]; +static uchar word[256]; +static int cpos = 0; +static bool init = FALSE; +static void (*state)(uchar ch); +static bool quote; + +static void s_hex(uchar ch); +static void s_num(uchar ch); +static void s_cmd(uchar ch); +static void s_leadcmd(uchar ch); +static void s_abbrev(uchar ch); +static void s_point(uchar ch); +static void s_word(uchar ch); +static void s_idle(uchar ch); + +static void s_hex(uchar ch) +{ + switch(ch) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'd': + case 'D': + case 'e': + case 'E': + case 'f': + case 'F': + word[cpos++] = ch; + break; + default: + word[cpos] = 0; + number(word); + state = s_idle; + s_idle(ch); + } +} + +static void s_num(uchar ch) +{ + switch(map[ch]) + { + case CH_NUMERIC: + word[cpos++] = ch; + break; + default: + switch(ch) + { + case 'e': + case '^': + word[cpos++] = ch; + number(word); + cpos = 0; + spo_word("raised"); + spo_word("to"); + spo_word("the"); + spo_word("power"); + break; + case ':': + case '/': + case '.': + word[cpos++] = ch; + break; + case '%': + word[cpos] = 0; + number(word); + state = s_idle; + spo_word("percent"); + break; + case 'x': + case 'X': + if(cpos == 1) + { + cpos = 0; + state = s_hex; + break; + } + default: + word[cpos] = 0; + number(word); + state = s_idle; + s_idle(ch); + } + } +} + +static void s_cmd(uchar ch) +{ + if(ch == '>') + { + word[cpos] = 0; + spo_cmd((char *)word); + state = s_idle; + } + else + word[cpos++] = ch; +} + +static void s_leadcmd(uchar ch) +{ + if(ch == '<') + state = s_cmd; + else + { + state = s_idle; + s_idle(ch); + } +} + +static void s_abbrev(uchar ch) +{ + switch(map[ch]) + { + case CH_SPACE: + abbrev((char *)word); + state = s_idle; + break; + default: + spo_word((char *)word); + cpos = 0; + spo_word("dot"); + state = s_word; + s_word(ch); + } +} + +static void s_point(uchar ch) +{ + switch(map[ch]) + { + case CH_ALPHA: + state = s_word; + case CH_PERIOD: + spo_word("dot"); + break; + case CH_NUMERIC: + spo_word("point"); + state = s_num; + break; + default: + state = s_idle; + break; + } +} + +static void s_word(uchar ch) +{ + switch(map[ch]) + { + case CH_PERIOD: + if(!cpos) + state = s_point; + else + state = s_abbrev; + word[cpos++] = '.'; + word[cpos] = 0; + break; + case CH_PUNCT: + case CH_ALPHA: + case CH_NUMERIC: + if(cpos < 255) + word[cpos++] = ch; + break; + case CH_SPACE: + word[cpos] = 0; + spo_word((char *)word); + state = s_idle; + break; + default: + switch(ch) + { + case '\'': + word[cpos++] = ch; + break; + default: + word[cpos] = 0; + spo_word((char *)word); + spo_pause(P_WORD); + state = s_idle; + s_idle(ch); + } + } +} + +static void s_idle(uchar ch) +{ + cpos = 0; + switch(map[ch]) + { + case CH_NUMERIC: + state = s_num; + s_num(ch); + break; + case CH_ALPHA: + state = s_word; + s_word(ch); + break; + case CH_ESCAPE: + state = s_leadcmd; + break; + case CH_SPACE: + spo_pause(P_WORD); + break; + case CH_QUOTE: + if(quote) + { + spo_word("end"); + quote = FALSE; + } + else + quote = TRUE; + spo_word("quote"); + break; + default: + switch(ch) + { + case '$': + word[0] = '$'; + cpos = 1; + state = s_num; + break; + case '*': + spo_word("times"); + break; + case '/': + spo_word("divided"); + spo_word("by"); + break; + case '+': + spo_word("plus"); + break; + case '-': + spo_word("minus"); + break; + case '&': + spo_word("and"); + break; + case '|': + spo_word("or"); + break; + case '~': + spo_word("not"); + break; + case ')': + spo_word("end"); + case '(': + spo_word("parenthesis"); + break; + case '=': + spo_word("equals"); + break; + case '<': + spo_word("less"); + spo_word("than"); + break; + case '>': + spo_word("greater"); + spo_word("than"); + break; + default: + spo_pause(P_WORD); + } + } +} + +void chars(FILE *fp) +{ + int i, ch; + + quote = FALSE; + state = s_idle; + + if(!init) + { + for(i = 0; i < 256; ++i) + map[i] = CH_IGNORE; + + map[27] = CH_ESCAPE; + + for(i = 33; i < 127; ++i) + map[i] = CH_PUNCT; + + map[9] = map[13] = map[10] = map[32] = CH_SPACE; + for(i = 48; i < 58; ++i) + map[i] = CH_NUMERIC; + + for(i = 0; i < 26; ++i) + { + map[i + 65] = CH_ALPHA; + map[i + 97] = CH_ALPHA; + } + map['.'] = CH_PERIOD; + map['\"'] = CH_QUOTE; + } + + while(EOF != (ch = fgetc(fp))) + (*state)(ch); + + (*state)(0); +} -- cgit v1.2.3-54-g00ecf