|
Boost : |
From: Phil Endecott (spam_from_boost_dev_at_[hidden])
Date: 2008-08-18 17:25:10
Andrey Semashev wrote:
> Phil Endecott wrote:
>> Dear All,
>>
>> Here's another FSM example which I hope is a bit less trivial than the
>> last one. It's for the escape sequence handling in a terminal
>> emulator.
>> My view is that the ad-hoc version of the code is sufficiently readable
>> and efficient for my needs, and that the Boost.FSM version does not
>> improve on it.
>
> Actually, the ad-hoc code is a good example for what is known as
> spagetti-style
Can you elaborate on why you say that? To me, "spagetti" code is code
where the flow-of-control goes all over the place in a complex and not
easily discernible pattern. In my "ad-hoc" implementation, the main
flow-of-control is contained in a single function which all fits on the
screen at the same time and has if and switch statements nested at most
4 deep. If it's the depth of nesting that you dislike it could easily
be flattened like this:
void process_control_char(char c) {
switch (c) {
....
case 13: carriage_return(); break;
....
case 26: // This code abandons any escape sequence that is in progress
state = normal; break;
case 27: // Escape
state = esc; break;
....
}
}
void process_char_normal_state(char c) {
write_normal_char(c);
}
void process_char_esc_state(char c) {
switch (c) {
....
case 'M': cursor_line_up(); state=normal; break;
....
case '[': state=csi; nparams=0; break;
default: state=normal; break;
}
}
void process_char_csi_state(char c) {
// split this up some more if you prefer.
if (isdigit(c)) {
if (nparams==0) {
nparams=1;
params[0]=0;
}
params[nparams-1] = params[nparams1]*10 + (c-'0');
} else if (c==';') {
if (nparams>=MAX_PARAMS) {
return;
}
nparams++;
params[nparams-1] = 0;
} else {
switch (c) {
....
case 'A': csi_CUU(); break;
....
}
state = normal;
}
}
void process_char(char c) {
// Control chars like tab, newline etc. work even inside
// escape sequences:
if (c <= 31) {
process_control_char(c);
} else {
switch (state) {
case normal: process_char_normal_state(c); break;
case esc: process_char_esc_state(c); break;
case csi: process_char_csi_state(c); break;
}
}
}
> Below is an improved version of the
> terminal, with corrected mistakes and categorized events.
A couple of questions:
- Does it correctly handle digits in normal mode?
- How can I access the screen and cursor position from outside? (Or, if
I can't access the content of the states from outside, how can I access
an externally-stored screen and cursor from inside the states?)
Phil.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk