in speakup/main.c [1936:2019]
static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key)
{
static u_char goto_buf[8];
static int num;
int maxlen;
char *cp;
u16 wch;
if (type == KT_SPKUP && ch == SPEAKUP_GOTO)
goto do_goto;
if (type == KT_LATIN && ch == '\n')
goto do_goto;
if (type != 0)
goto oops;
if (ch == 8) {
u16 wch;
if (num == 0)
return -1;
wch = goto_buf[--num];
goto_buf[num] = '\0';
spkup_write(&wch, 1);
return 1;
}
if (ch < '+' || ch > 'y')
goto oops;
wch = ch;
goto_buf[num++] = ch;
goto_buf[num] = '\0';
spkup_write(&wch, 1);
maxlen = (*goto_buf >= '0') ? 3 : 4;
if ((ch == '+' || ch == '-') && num == 1)
return 1;
if (ch >= '0' && ch <= '9' && num < maxlen)
return 1;
if (num < maxlen - 1 || num > maxlen)
goto oops;
if (ch < 'x' || ch > 'y') {
oops:
if (!spk_killed)
synth_printf(" %s\n", spk_msg_get(MSG_GOTO_CANCELED));
goto_buf[num = 0] = '\0';
spk_special_handler = NULL;
return 1;
}
/* Do not replace with kstrtoul: here we need cp to be updated */
goto_pos = simple_strtoul(goto_buf, &cp, 10);
if (*cp == 'x') {
if (*goto_buf < '0')
goto_pos += spk_x;
else if (goto_pos > 0)
goto_pos--;
if (goto_pos >= vc->vc_cols)
goto_pos = vc->vc_cols - 1;
goto_x = 1;
} else {
if (*goto_buf < '0')
goto_pos += spk_y;
else if (goto_pos > 0)
goto_pos--;
if (goto_pos >= vc->vc_rows)
goto_pos = vc->vc_rows - 1;
goto_x = 0;
}
goto_buf[num = 0] = '\0';
do_goto:
spk_special_handler = NULL;
spk_parked |= 0x01;
if (goto_x) {
spk_pos -= spk_x * 2;
spk_x = goto_pos;
spk_pos += goto_pos * 2;
say_word(vc);
} else {
spk_y = goto_pos;
spk_pos = vc->vc_origin + (goto_pos * vc->vc_size_row);
say_line(vc);
}
return 1;
}