-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcmdCharDef.cpp
233 lines (216 loc) · 8.19 KB
/
cmdCharDef.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/****************************************************************************
FileName [ cmdCharDef.cpp ]
PackageName [ cmd ]
Synopsis [ Process keyboard inputs ]
Author [ Chung-Yang (Ric) Huang ]
Copyright [ Copyleft(c) 2007-present LaDs(III), GIEE, NTU, Taiwan ]
****************************************************************************/
#include <iostream>
#include <iomanip>
#include <termios.h>
#include <stdlib.h>
#include <ctype.h>
#include <cassert>
#include "cmdCharDef.h"
using namespace std;
//----------------------------------------------------------------------
// Global static funcitons
//----------------------------------------------------------------------
static struct termios stored_settings;
static void reset_keypress(void)
{
tcsetattr(0,TCSANOW,&stored_settings);
}
static void set_keypress(void)
{
struct termios new_settings;
tcgetattr(0,&stored_settings);
new_settings = stored_settings;
new_settings.c_lflag &= (~ICANON);
new_settings.c_lflag &= (~ECHO);
new_settings.c_cc[VTIME] = 0;
tcgetattr(0,&stored_settings);
new_settings.c_cc[VMIN] = 1;
tcsetattr(0,TCSANOW,&new_settings);
}
//----------------------------------------------------------------------
// Global funcitons
//----------------------------------------------------------------------
char mygetc(istream& istr)//convert istream to char
{
char ch;
set_keypress();
istr.unsetf(ios_base::skipws);
istr >> ch;
istr.setf(ios_base::skipws);
reset_keypress();
#ifdef TEST_ASC
cout << left << setw(6) << int(ch);
#endif // TEST_ASC
return ch;
}
void mybeep()
{
cout << char(BEEP_CHAR);
}
inline ParseChar returnCh(int);
#ifndef TA_KB_SETTING
// YOU NEED TO CUSTOMIZE THIS PART...
// YOU NEED TO CUSTOMIZE THIS PART...
//
// Modify "cmdCharDef.h" to work with the following code
//
// Make sure you DO NOT define TA_KB_SETTING in your Makefile
//
ParseChar
getChar(istream& istr)
{
char ch = mygetc(istr);
if (istr.eof())
return returnCh(INPUT_END_KEY);
switch (ch) {
// Simple keys: one code for one key press
// -- The following should be platform-independent
case LINE_BEGIN_KEY: // Ctrl-a
return returnCh(HOME_KEY);
case LINE_END_KEY: // Ctrl-e
case INPUT_END_KEY: // Ctrl-d
case TAB_KEY: // tab('\t') or Ctrl-i
case NEWLINE_KEY: // enter('\n') or ctrl-m
return returnCh(ch);
// TODO... Check and change if necessary!!!!!!
// -- The following simple/combo keys are platform-dependent
// You should test to check the returned codes of these key presses
// -- You should either modify the "enum ParseChar" definitions in
// "cmdCharDef.h", or revise the control flow of the "case ESC" below
//
// -- You need to handle:
// { BACK_SPACE_KEY, ARROW_UP/DOWN/RIGHT/LEFT,
// HOME/END/PG_UP/PG_DOWN/INSERT/DELETE }
case BACK_SPACE_KEY:
return returnCh(ch);
// Combo keys: multiple codes for one key press
// -- Usually starts with ESC key, so we check the "case ESC"
// case ESC_KEY:
case ESC_KEY: {
char combo = mygetc(istr);
// Note: ARROW_KEY_INT == MOD_KEY_INT, so we only check MOD_KEY_INT
if (combo == char(MOD_KEY_INT)) {
char key = mygetc(istr);
if ((key >= char(MOD_KEY_BEGIN)) && (key <= char(MOD_KEY_END))) {
if (mygetc(istr) == MOD_KEY_DUMMY)
return returnCh(int(key) + MOD_KEY_FLAG);
else return returnCh(UNDEFINED_KEY);
}
else if ((key >= char(ARROW_KEY_BEGIN)) &&
(key <= char(ARROW_KEY_END)))
return returnCh(int(key) + ARROW_KEY_FLAG);
else return returnCh(UNDEFINED_KEY);
}
else { mybeep(); return getChar(istr); }
}
// For the remaining printable and undefined keys
default:
if (isprint(ch)) return returnCh(ch);
else return returnCh(UNDEFINED_KEY);
}
return returnCh(UNDEFINED_KEY);
}
#else // TA_KB_SETTING is defined
// DO NOT CHANGE THIS PART...
// DO NOT CHANGE THIS PART...
//
// This part will be used by TA to test your program.
//
// TA will use "make -DTA_KB_SETTING" to test your program
//
ParseChar
getChar(istream& istr)
{
char ch = mygetc(istr);
if (istr.eof())
return returnCh(INPUT_END_KEY);
switch (ch) {
// Simple keys: one code for one key press
// -- The following should be platform-independent
case LINE_BEGIN_KEY: // Ctrl-a
case LINE_END_KEY: // Ctrl-e
case INPUT_END_KEY: // Ctrl-d
case TAB_KEY: // tab('\t') or Ctrl-i
case NEWLINE_KEY: // enter('\n') or ctrl-m
return returnCh(ch);
// -- The following simple/combo keys are platform-dependent
// You should test to check the returned codes of these key presses
// -- You should either modify the "enum ParseChar" definitions in
// "cmdCharDef.h", or revise the control flow of the "case ESC" below
case BACK_SPACE_KEY:
return returnCh(ch);
// Combo keys: multiple codes for one key press
// -- Usually starts with ESC key, so we check the "case ESC"
case ESC_KEY: {
char combo = mygetc(istr);
// Note: ARROW_KEY_INT == MOD_KEY_INT, so we only check MOD_KEY_INT
if (combo == char(MOD_KEY_INT)) {
char key = mygetc(istr);
if ((key >= char(MOD_KEY_BEGIN)) && (key <= char(MOD_KEY_END))) {
if (mygetc(istr) == MOD_KEY_DUMMY)
return returnCh(int(key) + MOD_KEY_FLAG);
else return returnCh(UNDEFINED_KEY);
}
else if ((key >= char(ARROW_KEY_BEGIN)) &&
(key <= char(ARROW_KEY_END)))
return returnCh(int(key) + ARROW_KEY_FLAG);
else return returnCh(UNDEFINED_KEY);
}
else { mybeep(); return getChar(istr); }
}
// For the remaining printable and undefined keys
default:
if (isprint(ch)) return returnCh(ch);
else return returnCh(UNDEFINED_KEY);
}
return returnCh(UNDEFINED_KEY);
}
#endif // TA_KB_SETTING
inline ParseChar
returnCh(int ch)
{
#ifndef MAKE_REF
return ParseChar(ch);
#else
switch (ParseChar(ch)) {
case LINE_BEGIN_KEY : return ParseChar(TA_LINE_BEGIN_KEY);
case LINE_END_KEY : return ParseChar(TA_LINE_END_KEY);
case INPUT_END_KEY : return ParseChar(TA_INPUT_END_KEY);
case TAB_KEY : return ParseChar(TA_TAB_KEY);
case NEWLINE_KEY : return ParseChar(TA_NEWLINE_KEY);
case ESC_KEY : return ParseChar(TA_ESC_KEY);
case BACK_SPACE_KEY : return ParseChar(TA_BACK_SPACE_KEY);
case ARROW_KEY_FLAG : return ParseChar(TA_ARROW_KEY_FLAG);
case ARROW_KEY_INT : return ParseChar(TA_ARROW_KEY_INT);
case ARROW_UP_KEY : return ParseChar(TA_ARROW_UP_KEY);
case ARROW_DOWN_KEY : return ParseChar(TA_ARROW_DOWN_KEY);
case ARROW_RIGHT_KEY: return ParseChar(TA_ARROW_RIGHT_KEY);
case ARROW_LEFT_KEY : return ParseChar(TA_ARROW_LEFT_KEY);
// case ARROW_KEY_BEGIN: return ParseChar(TA_ARROW_KEY_BEGIN);
// case ARROW_KEY_END : return ParseChar(TA_ARROW_KEY_END);
case MOD_KEY_FLAG : return ParseChar(TA_MOD_KEY_FLAG);
// comment out because MOD_KEY_INT == ARROW_KEY_INT
// Uncomment it out if yours are different
// case MOD_KEY_INT : return ParseChar(TA_MOD_KEY_INT);
case HOME_KEY : return ParseChar(TA_HOME_KEY);
case INSERT_KEY : return ParseChar(TA_INSERT_KEY);
case DELETE_KEY : return ParseChar(TA_DELETE_KEY);
case END_KEY : return ParseChar(TA_END_KEY);
case PG_UP_KEY : return ParseChar(TA_PG_UP_KEY);
case PG_DOWN_KEY : return ParseChar(TA_PG_DOWN_KEY);
// case MOD_KEY_BEGIN : return ParseChar(TA_MOD_KEY_BEGIN);
// case MOD_KEY_END : return ParseChar(TA_MOD_KEY_END);
case MOD_KEY_DUMMY : return ParseChar(TA_MOD_KEY_DUMMY);
case UNDEFINED_KEY : return ParseChar(TA_UNDEFINED_KEY);
case BEEP_CHAR : return ParseChar(TA_BEEP_CHAR);
case BACK_SPACE_CHAR: return ParseChar(TA_BACK_SPACE_CHAR);
default : return ParseChar(ch);
}
#endif
}