Skip to content

Commit

Permalink
Added signed to unsigned functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
interkosmos committed Mar 8, 2024
1 parent 9652d17 commit 0024ca8
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 141 deletions.
129 changes: 66 additions & 63 deletions src/dm_tty.f90
Original file line number Diff line number Diff line change
Expand Up @@ -435,21 +435,16 @@ integer function dm_tty_set_attributes(tty) result(rc)
!! * `E_INVALID` if TTY is not connected.
!! * `E_SYSTEM` if system calls failed.
use :: unix
use :: dm_util

type(tty_type), intent(inout) :: tty !! TTY type.

integer(kind=c_tcflag_t) :: c_cflag
integer(kind=c_tcflag_t) :: c_iflag
integer(kind=c_tcflag_t) :: c_lflag
integer(kind=c_tcflag_t) :: c_oflag

integer(kind=c_speed_t) :: baud_rate
integer(kind=c_int) :: byte_size
integer(kind=c_int) :: parity
integer(kind=c_int) :: stop_bits
integer(kind=c_int64_t) :: byte_size
integer(kind=c_int64_t) :: parity
integer(kind=c_int64_t) :: stop_bits

integer(kind=c_int), target :: stat
type(c_termios) :: termios

rc = E_INVALID
if (tty%fd < 0) return
Expand Down Expand Up @@ -540,60 +535,68 @@ integer function dm_tty_set_attributes(tty) result(rc)

rc = E_SYSTEM

! Get current attributes.
stat = c_tcgetattr(tty%fd, termios)
if (stat /= 0) return

! Set baud rate (I/O).
stat = c_cfsetispeed(termios, baud_rate); if (stat /= 0) return
stat = c_cfsetospeed(termios, baud_rate); if (stat /= 0) return

! Modes.
c_iflag = int(c_uint_to_int(termios%c_iflag), kind=c_tcflag_t)
c_oflag = int(c_uint_to_int(termios%c_oflag), kind=c_tcflag_t)
c_cflag = int(c_uint_to_int(termios%c_cflag), kind=c_tcflag_t)
c_lflag = int(c_uint_to_int(termios%c_lflag), kind=c_tcflag_t)

! Input modes.
c_iflag = iand(c_iflag, not(IGNBRK + BRKINT + PARMRK + ISTRIP + INLCR + IGNCR + ICRNL)) ! No special handling of received bytes.
c_iflag = iand(c_iflag, not(IXON + IXOFF + IXANY)) ! Turn XON/XOFF control off.

! Output modes.
c_oflag = iand(c_oflag, not(OPOST)) ! No special interpretation of output bytes.

! Control modes.
c_cflag = iand(c_cflag, not(CSIZE)) ! Unset byte size.
c_cflag = iand(c_cflag, not(CSTOPB)) ! Unset stop bits.
c_cflag = iand(c_cflag, not(ior(PARENB, PARODD))) ! Unset parity.
c_cflag = ior (c_cflag, byte_size) ! Set byte size.
c_cflag = ior (c_cflag, stop_bits) ! Set stop bits.
c_cflag = ior (c_cflag, parity) ! Set parity.
c_cflag = ior (c_cflag, ior(CLOCAL, CREAD)) ! Ignore modem controls, enable reading.

! Local modes.
c_lflag = iand(c_lflag, not(ECHO + ECHOE + ECHONL)) ! No echo.
c_lflag = iand(c_lflag, not(IEXTEN)) ! No implementation-defined input processing.
c_lflag = iand(c_lflag, not(ICANON)) ! No canonical processing.
c_lflag = iand(c_lflag, not(ISIG)) ! No signal chars.

termios%c_iflag = c_iflag
termios%c_oflag = c_oflag
termios%c_cflag = c_cflag
termios%c_lflag = c_lflag

if (tty%blocking) then
! Minimum number of characters for non-canonical read.
termios%c_cc(VMIN) = 1_c_cc_t
termios%c_cc(VTIME) = 0_c_cc_t
else
! Timeout in deciseconds for non-canonical read.
termios%c_cc(VMIN) = 0_c_cc_t
termios%c_cc(VTIME) = int(max(0, min(255, tty%timeout * 10)), kind=c_cc_t)
end if

! Set attributes.
stat = c_tcsetattr(tty%fd, TCSANOW, termios)
if (stat /= 0) return
termios_block: block
integer(kind=c_int64_t) :: c_cflag
integer(kind=c_int64_t) :: c_iflag
integer(kind=c_int64_t) :: c_lflag
integer(kind=c_int64_t) :: c_oflag
type(c_termios) :: termios

! Get current attributes.
stat = c_tcgetattr(tty%fd, termios)
if (stat /= 0) return

! Set baud rate (I/O).
stat = c_cfsetispeed(termios, baud_rate); if (stat /= 0) return
stat = c_cfsetospeed(termios, baud_rate); if (stat /= 0) return

! The joy of working with unsigned integers in Fortran ...
c_iflag = dm_to_signed(termios%c_iflag)
c_oflag = dm_to_signed(termios%c_oflag)
c_cflag = dm_to_signed(termios%c_cflag)
c_lflag = dm_to_signed(termios%c_lflag)

! Input modes.
c_iflag = iand(c_iflag, not(int(IGNBRK + BRKINT + PARMRK + ISTRIP + INLCR + IGNCR + ICRNL, kind=c_int64_t))) ! No special handling of received bytes.
c_iflag = iand(c_iflag, not(int(IXON + IXOFF + IXANY, kind=c_int64_t))) ! Turn XON/XOFF control off.

! Output modes.
c_oflag = iand(c_oflag, not(int(OPOST, kind=c_int64_t))) ! No special interpretation of output bytes.

! Control modes.
c_cflag = iand(c_cflag, not(int(CSIZE, kind=c_int64_t))) ! Unset byte size.
c_cflag = iand(c_cflag, not(int(CSTOPB, kind=c_int64_t))) ! Unset stop bits.
c_cflag = iand(c_cflag, not(int(PARENB + PARODD, kind=c_int64_t))) ! Unset parity.
c_cflag = ior (c_cflag, byte_size) ! Set byte size.
c_cflag = ior (c_cflag, stop_bits) ! Set stop bits.
c_cflag = ior (c_cflag, parity) ! Set parity.
c_cflag = ior (c_cflag, int(CLOCAL + CREAD, kind=c_int64_t)) ! Ignore modem controls, enable reading.

! Local modes.
c_lflag = iand(c_lflag, not(int(ECHO + ECHOE + ECHONL, kind=c_int64_t))) ! No echo.
c_lflag = iand(c_lflag, not(int(IEXTEN, kind=c_int64_t))) ! No implementation-defined input processing.
c_lflag = iand(c_lflag, not(int(ICANON, kind=c_int64_t))) ! No canonical processing.
c_lflag = iand(c_lflag, not(int(ISIG, kind=c_int64_t))) ! No signal chars.

termios%c_iflag = dm_to_unsigned(c_iflag)
termios%c_oflag = dm_to_unsigned(c_oflag)
termios%c_cflag = dm_to_unsigned(c_cflag)
termios%c_lflag = dm_to_unsigned(c_lflag)

if (tty%blocking) then
! Minimum number of characters for non-canonical read.
termios%c_cc(VMIN) = 1_c_cc_t
termios%c_cc(VTIME) = 0_c_cc_t
else
! Timeout in deciseconds for non-canonical read.
termios%c_cc(VMIN) = 0_c_cc_t
termios%c_cc(VTIME) = int(max(0, min(255, tty%timeout * 10)), kind=c_cc_t)
end if

! Set attributes.
stat = c_tcsetattr(tty%fd, TCSANOW, termios)
if (stat /= 0) return
end block termios_block

! Set RTS, DTR.
if (tty%rts .or. tty%dtr) then
Expand Down
Loading

0 comments on commit 0024ca8

Please sign in to comment.