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