18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci#include <linux/ctype.h>
38c2ecf20Sopenharmony_ci#include "spk_types.h"
48c2ecf20Sopenharmony_ci#include "spk_priv.h"
58c2ecf20Sopenharmony_ci#include "speakup.h"
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_cistatic struct st_var_header var_headers[] = {
88c2ecf20Sopenharmony_ci	{ "version", VERSION, VAR_PROC, NULL, NULL },
98c2ecf20Sopenharmony_ci	{ "synth_name", SYNTH, VAR_PROC, NULL, NULL },
108c2ecf20Sopenharmony_ci	{ "keymap", KEYMAP, VAR_PROC, NULL, NULL },
118c2ecf20Sopenharmony_ci	{ "silent", SILENT, VAR_PROC, NULL, NULL },
128c2ecf20Sopenharmony_ci	{ "punc_some", PUNC_SOME, VAR_PROC, NULL, NULL },
138c2ecf20Sopenharmony_ci	{ "punc_most", PUNC_MOST, VAR_PROC, NULL, NULL },
148c2ecf20Sopenharmony_ci	{ "punc_all", PUNC_ALL, VAR_PROC, NULL, NULL },
158c2ecf20Sopenharmony_ci	{ "delimiters", DELIM, VAR_PROC, NULL, NULL },
168c2ecf20Sopenharmony_ci	{ "repeats", REPEATS, VAR_PROC, NULL, NULL },
178c2ecf20Sopenharmony_ci	{ "ex_num", EXNUMBER, VAR_PROC, NULL, NULL },
188c2ecf20Sopenharmony_ci	{ "characters", CHARS, VAR_PROC, NULL, NULL },
198c2ecf20Sopenharmony_ci	{ "synth_direct", SYNTH_DIRECT, VAR_PROC, NULL, NULL },
208c2ecf20Sopenharmony_ci	{ "caps_start", CAPS_START, VAR_STRING, spk_str_caps_start, NULL },
218c2ecf20Sopenharmony_ci	{ "caps_stop", CAPS_STOP, VAR_STRING, spk_str_caps_stop, NULL },
228c2ecf20Sopenharmony_ci	{ "delay_time", DELAY, VAR_TIME, NULL, NULL },
238c2ecf20Sopenharmony_ci	{ "trigger_time", TRIGGER, VAR_TIME, NULL, NULL },
248c2ecf20Sopenharmony_ci	{ "jiffy_delta", JIFFY, VAR_TIME, NULL, NULL },
258c2ecf20Sopenharmony_ci	{ "full_time", FULL, VAR_TIME, NULL, NULL },
268c2ecf20Sopenharmony_ci	{ "spell_delay", SPELL_DELAY, VAR_NUM, &spk_spell_delay, NULL },
278c2ecf20Sopenharmony_ci	{ "bleeps", BLEEPS, VAR_NUM, &spk_bleeps, NULL },
288c2ecf20Sopenharmony_ci	{ "attrib_bleep", ATTRIB_BLEEP, VAR_NUM, &spk_attrib_bleep, NULL },
298c2ecf20Sopenharmony_ci	{ "bleep_time", BLEEP_TIME, VAR_TIME, &spk_bleep_time, NULL },
308c2ecf20Sopenharmony_ci	{ "cursor_time", CURSOR_TIME, VAR_TIME, NULL, NULL },
318c2ecf20Sopenharmony_ci	{ "punc_level", PUNC_LEVEL, VAR_NUM, &spk_punc_level, NULL },
328c2ecf20Sopenharmony_ci	{ "reading_punc", READING_PUNC, VAR_NUM, &spk_reading_punc, NULL },
338c2ecf20Sopenharmony_ci	{ "say_control", SAY_CONTROL, VAR_NUM, &spk_say_ctrl, NULL },
348c2ecf20Sopenharmony_ci	{ "say_word_ctl", SAY_WORD_CTL, VAR_NUM, &spk_say_word_ctl, NULL },
358c2ecf20Sopenharmony_ci	{ "no_interrupt", NO_INTERRUPT, VAR_NUM, &spk_no_intr, NULL },
368c2ecf20Sopenharmony_ci	{ "key_echo", KEY_ECHO, VAR_NUM, &spk_key_echo, NULL },
378c2ecf20Sopenharmony_ci	{ "bell_pos", BELL_POS, VAR_NUM, &spk_bell_pos, NULL },
388c2ecf20Sopenharmony_ci	{ "rate", RATE, VAR_NUM, NULL, NULL },
398c2ecf20Sopenharmony_ci	{ "pitch", PITCH, VAR_NUM, NULL, NULL },
408c2ecf20Sopenharmony_ci	{ "inflection", INFLECTION, VAR_NUM, NULL, NULL },
418c2ecf20Sopenharmony_ci	{ "vol", VOL, VAR_NUM, NULL, NULL },
428c2ecf20Sopenharmony_ci	{ "tone", TONE, VAR_NUM, NULL, NULL },
438c2ecf20Sopenharmony_ci	{ "punct", PUNCT, VAR_NUM, NULL, NULL   },
448c2ecf20Sopenharmony_ci	{ "voice", VOICE, VAR_NUM, NULL, NULL },
458c2ecf20Sopenharmony_ci	{ "freq", FREQUENCY, VAR_NUM, NULL, NULL },
468c2ecf20Sopenharmony_ci	{ "lang", LANG, VAR_NUM, NULL, NULL },
478c2ecf20Sopenharmony_ci	{ "chartab", CHARTAB, VAR_PROC, NULL, NULL },
488c2ecf20Sopenharmony_ci	{ "direct", DIRECT, VAR_NUM, NULL, NULL },
498c2ecf20Sopenharmony_ci	{ "pause", PAUSE, VAR_STRING, spk_str_pause, NULL },
508c2ecf20Sopenharmony_ci};
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistatic struct st_var_header *var_ptrs[MAXVARS] = { NULL, NULL, NULL };
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistatic struct punc_var_t punc_vars[] = {
558c2ecf20Sopenharmony_ci	{ PUNC_SOME, 1 },
568c2ecf20Sopenharmony_ci	{ PUNC_MOST, 2 },
578c2ecf20Sopenharmony_ci	{ PUNC_ALL, 3 },
588c2ecf20Sopenharmony_ci	{ DELIM, 4 },
598c2ecf20Sopenharmony_ci	{ REPEATS, 5 },
608c2ecf20Sopenharmony_ci	{ EXNUMBER, 6 },
618c2ecf20Sopenharmony_ci	{ -1, -1 },
628c2ecf20Sopenharmony_ci};
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ciint spk_chartab_get_value(char *keyword)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	int value = 0;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	if (!strcmp(keyword, "ALPHA"))
698c2ecf20Sopenharmony_ci		value = ALPHA;
708c2ecf20Sopenharmony_ci	else if (!strcmp(keyword, "B_CTL"))
718c2ecf20Sopenharmony_ci		value = B_CTL;
728c2ecf20Sopenharmony_ci	else if (!strcmp(keyword, "WDLM"))
738c2ecf20Sopenharmony_ci		value = WDLM;
748c2ecf20Sopenharmony_ci	else if (!strcmp(keyword, "A_PUNC"))
758c2ecf20Sopenharmony_ci		value = A_PUNC;
768c2ecf20Sopenharmony_ci	else if (!strcmp(keyword, "PUNC"))
778c2ecf20Sopenharmony_ci		value = PUNC;
788c2ecf20Sopenharmony_ci	else if (!strcmp(keyword, "NUM"))
798c2ecf20Sopenharmony_ci		value = NUM;
808c2ecf20Sopenharmony_ci	else if (!strcmp(keyword, "A_CAP"))
818c2ecf20Sopenharmony_ci		value = A_CAP;
828c2ecf20Sopenharmony_ci	else if (!strcmp(keyword, "B_CAPSYM"))
838c2ecf20Sopenharmony_ci		value = B_CAPSYM;
848c2ecf20Sopenharmony_ci	else if (!strcmp(keyword, "B_SYM"))
858c2ecf20Sopenharmony_ci		value = B_SYM;
868c2ecf20Sopenharmony_ci	return value;
878c2ecf20Sopenharmony_ci}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_civoid speakup_register_var(struct var_t *var)
908c2ecf20Sopenharmony_ci{
918c2ecf20Sopenharmony_ci	static char nothing[2] = "\0";
928c2ecf20Sopenharmony_ci	int i;
938c2ecf20Sopenharmony_ci	struct st_var_header *p_header;
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci	BUG_ON(!var || var->var_id < 0 || var->var_id >= MAXVARS);
968c2ecf20Sopenharmony_ci	if (!var_ptrs[0]) {
978c2ecf20Sopenharmony_ci		for (i = 0; i < MAXVARS; i++) {
988c2ecf20Sopenharmony_ci			p_header = &var_headers[i];
998c2ecf20Sopenharmony_ci			var_ptrs[p_header->var_id] = p_header;
1008c2ecf20Sopenharmony_ci			p_header->data = NULL;
1018c2ecf20Sopenharmony_ci		}
1028c2ecf20Sopenharmony_ci	}
1038c2ecf20Sopenharmony_ci	p_header = var_ptrs[var->var_id];
1048c2ecf20Sopenharmony_ci	if (p_header->data)
1058c2ecf20Sopenharmony_ci		return;
1068c2ecf20Sopenharmony_ci	p_header->data = var;
1078c2ecf20Sopenharmony_ci	switch (p_header->var_type) {
1088c2ecf20Sopenharmony_ci	case VAR_STRING:
1098c2ecf20Sopenharmony_ci		spk_set_string_var(nothing, p_header, 0);
1108c2ecf20Sopenharmony_ci		break;
1118c2ecf20Sopenharmony_ci	case VAR_NUM:
1128c2ecf20Sopenharmony_ci	case VAR_TIME:
1138c2ecf20Sopenharmony_ci		spk_set_num_var(0, p_header, E_DEFAULT);
1148c2ecf20Sopenharmony_ci		break;
1158c2ecf20Sopenharmony_ci	default:
1168c2ecf20Sopenharmony_ci		break;
1178c2ecf20Sopenharmony_ci	}
1188c2ecf20Sopenharmony_ci}
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_civoid speakup_unregister_var(enum var_id_t var_id)
1218c2ecf20Sopenharmony_ci{
1228c2ecf20Sopenharmony_ci	struct st_var_header *p_header;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	BUG_ON(var_id < 0 || var_id >= MAXVARS);
1258c2ecf20Sopenharmony_ci	p_header = var_ptrs[var_id];
1268c2ecf20Sopenharmony_ci	p_header->data = NULL;
1278c2ecf20Sopenharmony_ci}
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_cistruct st_var_header *spk_get_var_header(enum var_id_t var_id)
1308c2ecf20Sopenharmony_ci{
1318c2ecf20Sopenharmony_ci	struct st_var_header *p_header;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci	if (var_id < 0 || var_id >= MAXVARS)
1348c2ecf20Sopenharmony_ci		return NULL;
1358c2ecf20Sopenharmony_ci	p_header = var_ptrs[var_id];
1368c2ecf20Sopenharmony_ci	if (!p_header->data)
1378c2ecf20Sopenharmony_ci		return NULL;
1388c2ecf20Sopenharmony_ci	return p_header;
1398c2ecf20Sopenharmony_ci}
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_cistruct st_var_header *spk_var_header_by_name(const char *name)
1428c2ecf20Sopenharmony_ci{
1438c2ecf20Sopenharmony_ci	int i;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	if (!name)
1468c2ecf20Sopenharmony_ci		return NULL;
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	for (i = 0; i < MAXVARS; i++) {
1498c2ecf20Sopenharmony_ci		if (strcmp(name, var_ptrs[i]->name) == 0)
1508c2ecf20Sopenharmony_ci			return var_ptrs[i];
1518c2ecf20Sopenharmony_ci	}
1528c2ecf20Sopenharmony_ci	return NULL;
1538c2ecf20Sopenharmony_ci}
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_cistruct var_t *spk_get_var(enum var_id_t var_id)
1568c2ecf20Sopenharmony_ci{
1578c2ecf20Sopenharmony_ci	BUG_ON(var_id < 0 || var_id >= MAXVARS);
1588c2ecf20Sopenharmony_ci	BUG_ON(!var_ptrs[var_id]);
1598c2ecf20Sopenharmony_ci	return var_ptrs[var_id]->data;
1608c2ecf20Sopenharmony_ci}
1618c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(spk_get_var);
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_cistruct punc_var_t *spk_get_punc_var(enum var_id_t var_id)
1648c2ecf20Sopenharmony_ci{
1658c2ecf20Sopenharmony_ci	struct punc_var_t *rv = NULL;
1668c2ecf20Sopenharmony_ci	struct punc_var_t *where;
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci	where = punc_vars;
1698c2ecf20Sopenharmony_ci	while ((where->var_id != -1) && (!rv)) {
1708c2ecf20Sopenharmony_ci		if (where->var_id == var_id)
1718c2ecf20Sopenharmony_ci			rv = where;
1728c2ecf20Sopenharmony_ci		else
1738c2ecf20Sopenharmony_ci			where++;
1748c2ecf20Sopenharmony_ci	}
1758c2ecf20Sopenharmony_ci	return rv;
1768c2ecf20Sopenharmony_ci}
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci/* handlers for setting vars */
1798c2ecf20Sopenharmony_ciint spk_set_num_var(int input, struct st_var_header *var, int how)
1808c2ecf20Sopenharmony_ci{
1818c2ecf20Sopenharmony_ci	int val;
1828c2ecf20Sopenharmony_ci	int *p_val = var->p_val;
1838c2ecf20Sopenharmony_ci	char buf[32];
1848c2ecf20Sopenharmony_ci	char *cp;
1858c2ecf20Sopenharmony_ci	struct var_t *var_data = var->data;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	if (!var_data)
1888c2ecf20Sopenharmony_ci		return -ENODATA;
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	val = var_data->u.n.value;
1918c2ecf20Sopenharmony_ci	switch (how) {
1928c2ecf20Sopenharmony_ci	case E_NEW_DEFAULT:
1938c2ecf20Sopenharmony_ci		if (input < var_data->u.n.low || input > var_data->u.n.high)
1948c2ecf20Sopenharmony_ci			return -ERANGE;
1958c2ecf20Sopenharmony_ci		var_data->u.n.default_val = input;
1968c2ecf20Sopenharmony_ci		return 0;
1978c2ecf20Sopenharmony_ci	case E_DEFAULT:
1988c2ecf20Sopenharmony_ci		val = var_data->u.n.default_val;
1998c2ecf20Sopenharmony_ci		break;
2008c2ecf20Sopenharmony_ci	case E_SET:
2018c2ecf20Sopenharmony_ci		val = input;
2028c2ecf20Sopenharmony_ci		break;
2038c2ecf20Sopenharmony_ci	case E_INC:
2048c2ecf20Sopenharmony_ci		val += input;
2058c2ecf20Sopenharmony_ci		break;
2068c2ecf20Sopenharmony_ci	case E_DEC:
2078c2ecf20Sopenharmony_ci		val -= input;
2088c2ecf20Sopenharmony_ci		break;
2098c2ecf20Sopenharmony_ci	}
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	if (val < var_data->u.n.low || val > var_data->u.n.high)
2128c2ecf20Sopenharmony_ci		return -ERANGE;
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	var_data->u.n.value = val;
2158c2ecf20Sopenharmony_ci	if (var->var_type == VAR_TIME && p_val) {
2168c2ecf20Sopenharmony_ci		*p_val = msecs_to_jiffies(val);
2178c2ecf20Sopenharmony_ci		return 0;
2188c2ecf20Sopenharmony_ci	}
2198c2ecf20Sopenharmony_ci	if (p_val)
2208c2ecf20Sopenharmony_ci		*p_val = val;
2218c2ecf20Sopenharmony_ci	if (var->var_id == PUNC_LEVEL) {
2228c2ecf20Sopenharmony_ci		spk_punc_mask = spk_punc_masks[val];
2238c2ecf20Sopenharmony_ci		return 0;
2248c2ecf20Sopenharmony_ci	}
2258c2ecf20Sopenharmony_ci	if (var_data->u.n.multiplier != 0)
2268c2ecf20Sopenharmony_ci		val *= var_data->u.n.multiplier;
2278c2ecf20Sopenharmony_ci	val += var_data->u.n.offset;
2288c2ecf20Sopenharmony_ci	if (var->var_id < FIRST_SYNTH_VAR || !synth)
2298c2ecf20Sopenharmony_ci		return 0;
2308c2ecf20Sopenharmony_ci	if (synth->synth_adjust)
2318c2ecf20Sopenharmony_ci		return synth->synth_adjust(var);
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	if (!var_data->u.n.synth_fmt)
2348c2ecf20Sopenharmony_ci		return 0;
2358c2ecf20Sopenharmony_ci	if (var->var_id == PITCH)
2368c2ecf20Sopenharmony_ci		cp = spk_pitch_buff;
2378c2ecf20Sopenharmony_ci	else
2388c2ecf20Sopenharmony_ci		cp = buf;
2398c2ecf20Sopenharmony_ci	if (!var_data->u.n.out_str)
2408c2ecf20Sopenharmony_ci		sprintf(cp, var_data->u.n.synth_fmt, (int)val);
2418c2ecf20Sopenharmony_ci	else
2428c2ecf20Sopenharmony_ci		sprintf(cp, var_data->u.n.synth_fmt,
2438c2ecf20Sopenharmony_ci			var_data->u.n.out_str[val]);
2448c2ecf20Sopenharmony_ci	synth_printf("%s", cp);
2458c2ecf20Sopenharmony_ci	return 0;
2468c2ecf20Sopenharmony_ci}
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ciint spk_set_string_var(const char *page, struct st_var_header *var, int len)
2498c2ecf20Sopenharmony_ci{
2508c2ecf20Sopenharmony_ci	struct var_t *var_data = var->data;
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	if (!var_data)
2538c2ecf20Sopenharmony_ci		return -ENODATA;
2548c2ecf20Sopenharmony_ci	if (len > MAXVARLEN)
2558c2ecf20Sopenharmony_ci		return -E2BIG;
2568c2ecf20Sopenharmony_ci	if (!len) {
2578c2ecf20Sopenharmony_ci		if (!var_data->u.s.default_val)
2588c2ecf20Sopenharmony_ci			return 0;
2598c2ecf20Sopenharmony_ci		if (!var->p_val)
2608c2ecf20Sopenharmony_ci			var->p_val = var_data->u.s.default_val;
2618c2ecf20Sopenharmony_ci		if (var->p_val != var_data->u.s.default_val)
2628c2ecf20Sopenharmony_ci			strcpy((char *)var->p_val, var_data->u.s.default_val);
2638c2ecf20Sopenharmony_ci		return -ERESTART;
2648c2ecf20Sopenharmony_ci	} else if (var->p_val) {
2658c2ecf20Sopenharmony_ci		strcpy((char *)var->p_val, page);
2668c2ecf20Sopenharmony_ci	} else {
2678c2ecf20Sopenharmony_ci		return -E2BIG;
2688c2ecf20Sopenharmony_ci	}
2698c2ecf20Sopenharmony_ci	return 0;
2708c2ecf20Sopenharmony_ci}
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci/*
2738c2ecf20Sopenharmony_ci * spk_set_mask_bits sets or clears the punc/delim/repeat bits,
2748c2ecf20Sopenharmony_ci * if input is null uses the defaults.
2758c2ecf20Sopenharmony_ci * values for how: 0 clears bits of chars supplied,
2768c2ecf20Sopenharmony_ci * 1 clears allk, 2 sets bits for chars
2778c2ecf20Sopenharmony_ci */
2788c2ecf20Sopenharmony_ciint spk_set_mask_bits(const char *input, const int which, const int how)
2798c2ecf20Sopenharmony_ci{
2808c2ecf20Sopenharmony_ci	u_char *cp;
2818c2ecf20Sopenharmony_ci	short mask = spk_punc_info[which].mask;
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	if (how & 1) {
2848c2ecf20Sopenharmony_ci		for (cp = (u_char *)spk_punc_info[3].value; *cp; cp++)
2858c2ecf20Sopenharmony_ci			spk_chartab[*cp] &= ~mask;
2868c2ecf20Sopenharmony_ci	}
2878c2ecf20Sopenharmony_ci	cp = (u_char *)input;
2888c2ecf20Sopenharmony_ci	if (!cp) {
2898c2ecf20Sopenharmony_ci		cp = spk_punc_info[which].value;
2908c2ecf20Sopenharmony_ci	} else {
2918c2ecf20Sopenharmony_ci		for (; *cp; cp++) {
2928c2ecf20Sopenharmony_ci			if (*cp < SPACE)
2938c2ecf20Sopenharmony_ci				break;
2948c2ecf20Sopenharmony_ci			if (mask < PUNC) {
2958c2ecf20Sopenharmony_ci				if (!(spk_chartab[*cp] & PUNC))
2968c2ecf20Sopenharmony_ci					break;
2978c2ecf20Sopenharmony_ci			} else if (spk_chartab[*cp] & B_NUM) {
2988c2ecf20Sopenharmony_ci				break;
2998c2ecf20Sopenharmony_ci			}
3008c2ecf20Sopenharmony_ci		}
3018c2ecf20Sopenharmony_ci		if (*cp)
3028c2ecf20Sopenharmony_ci			return -EINVAL;
3038c2ecf20Sopenharmony_ci		cp = (u_char *)input;
3048c2ecf20Sopenharmony_ci	}
3058c2ecf20Sopenharmony_ci	if (how & 2) {
3068c2ecf20Sopenharmony_ci		for (; *cp; cp++)
3078c2ecf20Sopenharmony_ci			if (*cp > SPACE)
3088c2ecf20Sopenharmony_ci				spk_chartab[*cp] |= mask;
3098c2ecf20Sopenharmony_ci	} else {
3108c2ecf20Sopenharmony_ci		for (; *cp; cp++)
3118c2ecf20Sopenharmony_ci			if (*cp > SPACE)
3128c2ecf20Sopenharmony_ci				spk_chartab[*cp] &= ~mask;
3138c2ecf20Sopenharmony_ci	}
3148c2ecf20Sopenharmony_ci	return 0;
3158c2ecf20Sopenharmony_ci}
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_cichar *spk_strlwr(char *s)
3188c2ecf20Sopenharmony_ci{
3198c2ecf20Sopenharmony_ci	char *p;
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	if (!s)
3228c2ecf20Sopenharmony_ci		return NULL;
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_ci	for (p = s; *p; p++)
3258c2ecf20Sopenharmony_ci		*p = tolower(*p);
3268c2ecf20Sopenharmony_ci	return s;
3278c2ecf20Sopenharmony_ci}
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_cichar *spk_s2uchar(char *start, char *dest)
3308c2ecf20Sopenharmony_ci{
3318c2ecf20Sopenharmony_ci	int val;
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	/* Do not replace with kstrtoul: here we need start to be updated */
3348c2ecf20Sopenharmony_ci	val = simple_strtoul(skip_spaces(start), &start, 10);
3358c2ecf20Sopenharmony_ci	if (*start == ',')
3368c2ecf20Sopenharmony_ci		start++;
3378c2ecf20Sopenharmony_ci	*dest = (u_char)val;
3388c2ecf20Sopenharmony_ci	return start;
3398c2ecf20Sopenharmony_ci}
340