brintos

brintos / linux-shallow public Read only

0
0
Text · 8.2 KiB · 462f8d8 Raw
346 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <linux/ctype.h>3#include "spk_types.h"4#include "spk_priv.h"5#include "speakup.h"6 7static struct st_var_header var_headers[] = {8	{ "version", VERSION, VAR_PROC, NULL, NULL },9	{ "synth_name", SYNTH, VAR_PROC, NULL, NULL },10	{ "keymap", KEYMAP, VAR_PROC, NULL, NULL },11	{ "silent", SILENT, VAR_PROC, NULL, NULL },12	{ "punc_some", PUNC_SOME, VAR_PROC, NULL, NULL },13	{ "punc_most", PUNC_MOST, VAR_PROC, NULL, NULL },14	{ "punc_all", PUNC_ALL, VAR_PROC, NULL, NULL },15	{ "delimiters", DELIM, VAR_PROC, NULL, NULL },16	{ "repeats", REPEATS, VAR_PROC, NULL, NULL },17	{ "ex_num", EXNUMBER, VAR_PROC, NULL, NULL },18	{ "characters", CHARS, VAR_PROC, NULL, NULL },19	{ "synth_direct", SYNTH_DIRECT, VAR_PROC, NULL, NULL },20	{ "caps_start", CAPS_START, VAR_STRING, spk_str_caps_start, NULL },21	{ "caps_stop", CAPS_STOP, VAR_STRING, spk_str_caps_stop, NULL },22	{ "delay_time", DELAY, VAR_TIME, NULL, NULL },23	{ "trigger_time", TRIGGER, VAR_TIME, NULL, NULL },24	{ "jiffy_delta", JIFFY, VAR_TIME, NULL, NULL },25	{ "full_time", FULL, VAR_TIME, NULL, NULL },26	{ "flush_time", FLUSH, VAR_TIME, NULL, NULL },27	{ "spell_delay", SPELL_DELAY, VAR_NUM, &spk_spell_delay, NULL },28	{ "bleeps", BLEEPS, VAR_NUM, &spk_bleeps, NULL },29	{ "attrib_bleep", ATTRIB_BLEEP, VAR_NUM, &spk_attrib_bleep, NULL },30	{ "bleep_time", BLEEP_TIME, VAR_TIME, &spk_bleep_time, NULL },31	{ "cursor_time", CURSOR_TIME, VAR_TIME, NULL, NULL },32	{ "punc_level", PUNC_LEVEL, VAR_NUM, &spk_punc_level, NULL },33	{ "reading_punc", READING_PUNC, VAR_NUM, &spk_reading_punc, NULL },34	{ "say_control", SAY_CONTROL, VAR_NUM, &spk_say_ctrl, NULL },35	{ "say_word_ctl", SAY_WORD_CTL, VAR_NUM, &spk_say_word_ctl, NULL },36	{ "no_interrupt", NO_INTERRUPT, VAR_NUM, &spk_no_intr, NULL },37	{ "key_echo", KEY_ECHO, VAR_NUM, &spk_key_echo, NULL },38	{ "bell_pos", BELL_POS, VAR_NUM, &spk_bell_pos, NULL },39	{ "rate", RATE, VAR_NUM, NULL, NULL },40	{ "pitch", PITCH, VAR_NUM, NULL, NULL },41	{ "inflection", INFLECTION, VAR_NUM, NULL, NULL },42	{ "vol", VOL, VAR_NUM, NULL, NULL },43	{ "tone", TONE, VAR_NUM, NULL, NULL },44	{ "punct", PUNCT, VAR_NUM, NULL, NULL   },45	{ "voice", VOICE, VAR_NUM, NULL, NULL },46	{ "freq", FREQUENCY, VAR_NUM, NULL, NULL },47	{ "lang", LANG, VAR_NUM, NULL, NULL },48	{ "chartab", CHARTAB, VAR_PROC, NULL, NULL },49	{ "direct", DIRECT, VAR_NUM, NULL, NULL },50	{ "pause", PAUSE, VAR_STRING, spk_str_pause, NULL },51	{ "cur_phonetic", CUR_PHONETIC, VAR_NUM, &spk_cur_phonetic, NULL },52};53 54static struct st_var_header *var_ptrs[MAXVARS] = { NULL, NULL, NULL };55 56static struct punc_var_t punc_vars[] = {57	{ PUNC_SOME, 1 },58	{ PUNC_MOST, 2 },59	{ PUNC_ALL, 3 },60	{ DELIM, 4 },61	{ REPEATS, 5 },62	{ EXNUMBER, 6 },63	{ -1, -1 },64};65 66int spk_chartab_get_value(char *keyword)67{68	int value = 0;69 70	if (!strcmp(keyword, "ALPHA"))71		value = ALPHA;72	else if (!strcmp(keyword, "B_CTL"))73		value = B_CTL;74	else if (!strcmp(keyword, "WDLM"))75		value = WDLM;76	else if (!strcmp(keyword, "A_PUNC"))77		value = A_PUNC;78	else if (!strcmp(keyword, "PUNC"))79		value = PUNC;80	else if (!strcmp(keyword, "NUM"))81		value = NUM;82	else if (!strcmp(keyword, "A_CAP"))83		value = A_CAP;84	else if (!strcmp(keyword, "B_CAPSYM"))85		value = B_CAPSYM;86	else if (!strcmp(keyword, "B_SYM"))87		value = B_SYM;88	return value;89}90 91void speakup_register_var(struct var_t *var)92{93	static char nothing[2] = "\0";94	int i;95	struct st_var_header *p_header;96 97	BUG_ON(!var || var->var_id < 0 || var->var_id >= MAXVARS);98	if (!var_ptrs[0]) {99		for (i = 0; i < MAXVARS; i++) {100			p_header = &var_headers[i];101			var_ptrs[p_header->var_id] = p_header;102			p_header->data = NULL;103		}104	}105	p_header = var_ptrs[var->var_id];106	if (p_header->data)107		return;108	p_header->data = var;109	switch (p_header->var_type) {110	case VAR_STRING:111		spk_set_string_var(nothing, p_header, 0);112		break;113	case VAR_NUM:114	case VAR_TIME:115		spk_set_num_var(0, p_header, E_DEFAULT);116		break;117	default:118		break;119	}120}121 122void speakup_unregister_var(enum var_id_t var_id)123{124	struct st_var_header *p_header;125 126	BUG_ON(var_id < 0 || var_id >= MAXVARS);127	p_header = var_ptrs[var_id];128	p_header->data = NULL;129}130 131struct st_var_header *spk_get_var_header(enum var_id_t var_id)132{133	struct st_var_header *p_header;134 135	if (var_id < 0 || var_id >= MAXVARS)136		return NULL;137	p_header = var_ptrs[var_id];138	if (!p_header->data)139		return NULL;140	return p_header;141}142EXPORT_SYMBOL_GPL(spk_get_var_header);143 144struct st_var_header *spk_var_header_by_name(const char *name)145{146	int i;147 148	if (!name)149		return NULL;150 151	for (i = 0; i < MAXVARS; i++) {152		if (strcmp(name, var_ptrs[i]->name) == 0)153			return var_ptrs[i];154	}155	return NULL;156}157 158struct var_t *spk_get_var(enum var_id_t var_id)159{160	BUG_ON(var_id < 0 || var_id >= MAXVARS);161	BUG_ON(!var_ptrs[var_id]);162	return var_ptrs[var_id]->data;163}164EXPORT_SYMBOL_GPL(spk_get_var);165 166struct punc_var_t *spk_get_punc_var(enum var_id_t var_id)167{168	struct punc_var_t *rv = NULL;169	struct punc_var_t *where;170 171	where = punc_vars;172	while ((where->var_id != -1) && (!rv)) {173		if (where->var_id == var_id)174			rv = where;175		else176			where++;177	}178	return rv;179}180 181/* handlers for setting vars */182int spk_set_num_var(int input, struct st_var_header *var, int how)183{184	int val;185	int *p_val = var->p_val;186	char buf[32];187	char *cp;188	struct var_t *var_data = var->data;189 190	if (!var_data)191		return -ENODATA;192 193	val = var_data->u.n.value;194	switch (how) {195	case E_NEW_DEFAULT:196		if (input < var_data->u.n.low || input > var_data->u.n.high)197			return -ERANGE;198		var_data->u.n.default_val = input;199		return 0;200	case E_DEFAULT:201		val = var_data->u.n.default_val;202		break;203	case E_SET:204		val = input;205		break;206	case E_INC:207		val += input;208		break;209	case E_DEC:210		val -= input;211		break;212	}213 214	if (val < var_data->u.n.low || val > var_data->u.n.high)215		return -ERANGE;216 217	var_data->u.n.value = val;218	if (var->var_type == VAR_TIME && p_val) {219		*p_val = msecs_to_jiffies(val);220		return 0;221	}222	if (p_val)223		*p_val = val;224	if (var->var_id == PUNC_LEVEL) {225		spk_punc_mask = spk_punc_masks[val];226	}227	if (var_data->u.n.multiplier != 0)228		val *= var_data->u.n.multiplier;229	val += var_data->u.n.offset;230 231	if (!synth)232		return 0;233	if (synth->synth_adjust && synth->synth_adjust(synth, var))234		return 0;235	if (var->var_id < FIRST_SYNTH_VAR)236		return 0;237 238	if (!var_data->u.n.synth_fmt)239		return 0;240	if (var->var_id == PITCH)241		cp = spk_pitch_buff;242	else243		cp = buf;244	if (!var_data->u.n.out_str)245		sprintf(cp, var_data->u.n.synth_fmt, (int)val);246	else247		sprintf(cp, var_data->u.n.synth_fmt,248			var_data->u.n.out_str[val]);249	synth_printf("%s", cp);250	return 0;251}252EXPORT_SYMBOL_GPL(spk_set_num_var);253 254int spk_set_string_var(const char *page, struct st_var_header *var, int len)255{256	struct var_t *var_data = var->data;257 258	if (!var_data)259		return -ENODATA;260	if (len > MAXVARLEN)261		return -E2BIG;262	if (!len) {263		if (!var_data->u.s.default_val)264			return 0;265		if (!var->p_val)266			var->p_val = var_data->u.s.default_val;267		if (var->p_val != var_data->u.s.default_val)268			strcpy((char *)var->p_val, var_data->u.s.default_val);269		return -ERESTART;270	} else if (var->p_val) {271		strcpy((char *)var->p_val, page);272	} else {273		return -E2BIG;274	}275	return 0;276}277 278/*279 * spk_set_mask_bits sets or clears the punc/delim/repeat bits,280 * if input is null uses the defaults.281 * values for how: 0 clears bits of chars supplied,282 * 1 clears allk, 2 sets bits for chars283 */284int spk_set_mask_bits(const char *input, const int which, const int how)285{286	u_char *cp;287	short mask = spk_punc_info[which].mask;288 289	if (how & 1) {290		for (cp = (u_char *)spk_punc_info[3].value; *cp; cp++)291			spk_chartab[*cp] &= ~mask;292	}293	cp = (u_char *)input;294	if (!cp) {295		cp = spk_punc_info[which].value;296	} else {297		for (; *cp; cp++) {298			if (*cp < SPACE)299				break;300			if (mask < PUNC) {301				if (!(spk_chartab[*cp] & PUNC))302					break;303			} else if (spk_chartab[*cp] & B_NUM) {304				break;305			}306		}307		if (*cp)308			return -EINVAL;309		cp = (u_char *)input;310	}311	if (how & 2) {312		for (; *cp; cp++)313			if (*cp > SPACE)314				spk_chartab[*cp] |= mask;315	} else {316		for (; *cp; cp++)317			if (*cp > SPACE)318				spk_chartab[*cp] &= ~mask;319	}320	return 0;321}322 323char *spk_strlwr(char *s)324{325	char *p;326 327	if (!s)328		return NULL;329 330	for (p = s; *p; p++)331		*p = tolower(*p);332	return s;333}334 335char *spk_s2uchar(char *start, char *dest)336{337	int val;338 339	/* Do not replace with kstrtoul: here we need start to be updated */340	val = simple_strtoul(skip_spaces(start), &start, 10);341	if (*start == ',')342		start++;343	*dest = (u_char)val;344	return start;345}346