@@ -20,141 +20,161 @@ enum { Iflags, Oflags, Cflags, Lflags };
2020
2121/* Structure of the terminal_io record. Cf. unix.mli */
2222
23- static long terminal_io_descr [] = {
24- /* Input modes */
25- Bool , Iflags , IGNBRK , Bool , Iflags , BRKINT , Bool , Iflags , IGNPAR , Bool ,
26- Iflags , PARMRK , Bool , Iflags , INPCK , Bool , Iflags , ISTRIP , Bool , Iflags ,
27- INLCR , Bool , Iflags , IGNCR , Bool , Iflags , ICRNL , Bool , Iflags , IXON , Bool ,
28- Iflags , IXOFF ,
29- /* Output modes */
30- Bool , Oflags , OPOST ,
31- /* Control modes */
32- Speed , Output , Speed , Input , Enum , Cflags , 5 , 4 , CSIZE , CS5 , CS6 , CS7 , CS8 ,
33- Enum , Cflags , 1 , 2 , CSTOPB , 0 , CSTOPB , Bool , Cflags , CREAD , Bool , Cflags ,
34- PARENB , Bool , Cflags , PARODD , Bool , Cflags , HUPCL , Bool , Cflags , CLOCAL ,
35- /* Local modes */
36- Bool , Lflags , ISIG , Bool , Lflags , ICANON , Bool , Lflags , NOFLSH , Bool ,
37- Lflags , ECHO , Bool , Lflags , ECHOE , Bool , Lflags , ECHOK , Bool , Lflags ,
38- ECHONL ,
39- /* Control characters */
40- Char , VINTR , Char , VQUIT , Char , VERASE , Char , VKILL , Char , VEOF , Char , VEOL ,
41- Char , VMIN , Char , VTIME , Char , VSTART , Char , VSTOP , End };
23+ static tcflag_t * choose_field (struct termios * terminal_status , long field )
24+ {
25+ switch (field ) {
26+ case Iflags :
27+ return & terminal_status -> c_iflag ;
28+ case Oflags :
29+ return & terminal_status -> c_oflag ;
30+ case Cflags :
31+ return & terminal_status -> c_cflag ;
32+ case Lflags :
33+ return & terminal_status -> c_lflag ;
34+ default :
35+ return 0 ;
36+ }
37+ }
4238
43- static struct {
39+ struct speed_t {
4440 speed_t speed ;
4541 int baud ;
46- } speedtable [] = {{B50 , 50 },
47- {B75 , 75 },
48- {B110 , 110 },
49- {B134 , 134 },
50- {B150 , 150 },
42+ };
43+
44+ long _speedtable (struct speed_t dst []) {
45+ struct speed_t speedtable [] = {
46+ {B50 , 50 },
47+ {B75 , 75 },
48+ {B110 , 110 },
49+ {B134 , 134 },
50+ {B150 , 150 },
5151#ifdef B200
52- {B200 , 200 },
52+ {B200 , 200 },
5353#endif
54- {B300 , 300 },
55- {B600 , 600 },
56- {B1200 , 1200 },
57- {B1800 , 1800 },
58- {B2400 , 2400 },
59- {B4800 , 4800 },
60- {B9600 , 9600 },
61- {B19200 , 19200 },
62- {B38400 , 38400 },
54+ {B300 , 300 },
55+ {B600 , 600 },
56+ {B1200 , 1200 },
57+ {B1800 , 1800 },
58+ {B2400 , 2400 },
59+ {B4800 , 4800 },
60+ {B9600 , 9600 },
61+ {B19200 , 19200 },
62+ {B38400 , 38400 },
6363#ifdef B57600
64- {B57600 , 57600 },
64+ {B57600 , 57600 },
6565#endif
6666#ifdef B115200
67- {B115200 , 115200 },
67+ {B115200 , 115200 },
6868#endif
6969#ifdef B230400
70- {B230400 , 230400 },
70+ {B230400 , 230400 },
7171#endif
72- {B0 , 0 },
72+ {B0 , 0 },
7373
7474 /* Linux extensions */
7575#ifdef B460800
76- {B460800 , 460800 },
76+ {B460800 , 460800 },
7777#endif
7878#ifdef B500000
79- {B500000 , 500000 },
79+ {B500000 , 500000 },
8080#endif
8181#ifdef B576000
82- {B576000 , 576000 },
82+ {B576000 , 576000 },
8383#endif
8484#ifdef B921600
85- {B921600 , 921600 },
85+ {B921600 , 921600 },
8686#endif
8787#ifdef B1000000
88- {B1000000 , 1000000 },
88+ {B1000000 , 1000000 },
8989#endif
9090#ifdef B1152000
91- {B1152000 , 1152000 },
91+ {B1152000 , 1152000 },
9292#endif
9393#ifdef B1500000
94- {B1500000 , 1500000 },
94+ {B1500000 , 1500000 },
9595#endif
9696#ifdef B2000000
97- {B2000000 , 2000000 },
97+ {B2000000 , 2000000 },
9898#endif
9999#ifdef B2500000
100- {B2500000 , 2500000 },
100+ {B2500000 , 2500000 },
101101#endif
102102#ifdef B3000000
103- {B3000000 , 3000000 },
103+ {B3000000 , 3000000 },
104104#endif
105105#ifdef B3500000
106- {B3500000 , 3500000 },
106+ {B3500000 , 3500000 },
107107#endif
108108#ifdef B4000000
109- {B4000000 , 4000000 },
109+ {B4000000 , 4000000 },
110110#endif
111111
112- /* MacOS extensions */
112+ /* MacOS extensions */
113113#ifdef B7200
114- {B7200 , 7200 },
114+ {B7200 , 7200 },
115115#endif
116116#ifdef B14400
117- {B14400 , 14400 },
117+ {B14400 , 14400 },
118118#endif
119119#ifdef B28800
120- {B28800 , 28800 },
120+ {B28800 , 28800 },
121121#endif
122122#ifdef B76800
123- {B76800 , 76800 },
123+ {B76800 , 76800 },
124124#endif
125125
126126 /* Cygwin extensions (in addition to the Linux ones) */
127127#ifdef B128000
128- {B128000 , 128000 },
128+ {B128000 , 128000 },
129129#endif
130130#ifdef B256000
131- {B256000 , 256000 },
131+ {B256000 , 256000 },
132132#endif
133- };
133+ };
134134
135- #define NSPEEDS (sizeof(speedtable) / sizeof(speedtable[0]))
135+ if (dst != NULL ) memcpy (dst , speedtable , sizeof (speedtable ));
136+ return (sizeof (speedtable ) / sizeof (speedtable [0 ]));
137+ }
136138
137- static tcflag_t * choose_field (struct termios * terminal_status , long field )
138- {
139- switch (field ) {
140- case Iflags :
141- return & terminal_status -> c_iflag ;
142- case Oflags :
143- return & terminal_status -> c_oflag ;
144- case Cflags :
145- return & terminal_status -> c_cflag ;
146- case Lflags :
147- return & terminal_status -> c_lflag ;
148- default :
149- return 0 ;
150- }
139+ long _terminal_io_descr (long dst []) {
140+ long terminal_io_descr [] = {
141+ /* Input modes */
142+ Bool , Iflags , IGNBRK , Bool , Iflags , BRKINT , Bool , Iflags , IGNPAR , Bool ,
143+ Iflags , PARMRK , Bool , Iflags , INPCK , Bool , Iflags , ISTRIP , Bool , Iflags ,
144+ INLCR , Bool , Iflags , IGNCR , Bool , Iflags , ICRNL , Bool , Iflags , IXON , Bool ,
145+ Iflags , IXOFF ,
146+ /* Output modes */
147+ Bool , Oflags , OPOST ,
148+ /* Control modes */
149+ Speed , Output , Speed , Input , Enum , Cflags , 5 , 4 , CSIZE , CS5 , CS6 , CS7 , CS8 ,
150+ Enum , Cflags , 1 , 2 , CSTOPB , 0 , CSTOPB , Bool , Cflags , CREAD , Bool , Cflags ,
151+ PARENB , Bool , Cflags , PARODD , Bool , Cflags , HUPCL , Bool , Cflags , CLOCAL ,
152+ /* Local modes */
153+ Bool , Lflags , ISIG , Bool , Lflags , ICANON , Bool , Lflags , NOFLSH , Bool ,
154+ Lflags , ECHO , Bool , Lflags , ECHOE , Bool , Lflags , ECHOK , Bool , Lflags ,
155+ ECHONL ,
156+ /* Control characters */
157+ Char , VINTR , Char , VQUIT , Char , VERASE , Char , VKILL , Char , VEOF , Char , VEOL ,
158+ Char , VMIN , Char , VTIME , Char , VSTART , Char , VSTOP , End };
159+
160+ if (dst != NULL ) memcpy (dst , terminal_io_descr , sizeof (terminal_io_descr ));
161+ return (sizeof (terminal_io_descr ) / sizeof (long ));
151162}
152163
164+
153165void encode_terminal_status (struct termios * terminal_status , value * dst )
154166{
155167 long * pc ;
156168 int i ;
157169
170+ long _NSPEEDS = _speedtable (NULL );
171+ struct speed_t speedtable [_NSPEEDS ];
172+ _speedtable (speedtable );
173+
174+ long nterminal_io_descr = _terminal_io_descr (NULL );
175+ long terminal_io_descr [nterminal_io_descr ];
176+ _terminal_io_descr (terminal_io_descr );
177+
158178 for (pc = terminal_io_descr ; * pc != End ; dst ++ ) {
159179 switch (* pc ++ ) {
160180 case Bool : {
@@ -190,7 +210,7 @@ void encode_terminal_status(struct termios *terminal_status, value *dst)
190210 speed = cfgetispeed (terminal_status );
191211 break ;
192212 }
193- for (i = 0 ; i < NSPEEDS ; i ++ ) {
213+ for (i = 0 ; i < _NSPEEDS ; i ++ ) {
194214 if (speed == speedtable [i ].speed ) {
195215 * dst = Val_int (speedtable [i ].baud );
196216 break ;
@@ -212,6 +232,14 @@ int decode_terminal_status(struct termios *terminal_status, value *src)
212232 long * pc ;
213233 int i ;
214234
235+ long _NSPEEDS = _speedtable (NULL );
236+ struct speed_t speedtable [_NSPEEDS ];
237+ _speedtable (speedtable );
238+
239+ long nterminal_io_descr = _terminal_io_descr (NULL );
240+ long terminal_io_descr [nterminal_io_descr ];
241+ _terminal_io_descr (terminal_io_descr );
242+
215243 for (pc = terminal_io_descr ; * pc != End ; src ++ ) {
216244 switch (* pc ++ ) {
217245 case Bool : {
@@ -242,7 +270,7 @@ int decode_terminal_status(struct termios *terminal_status, value *src)
242270 int which = * pc ++ ;
243271 int baud = Int_val (* src );
244272 int res = 0 ;
245- for (i = 0 ; i < NSPEEDS ; i ++ ) {
273+ for (i = 0 ; i < _NSPEEDS ; i ++ ) {
246274 if (baud == speedtable [i ].baud ) {
247275 switch (which ) {
248276 case Output :
0 commit comments