source: tests/coroutine/devicedriver.cfa @ c82dad4

Last change on this file since c82dad4 was 3ac5fd8, checked in by Peter A. Buhr <pabuhr@…>, 3 months ago

first attempt changing end-of-file to an exception

  • Property mode set to 100644
File size: 2.4 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// devicedriver.cfa --
8//
9// Author           : Peter A. Buhr
10// Created On       : Sat Mar 16 15:30:34 2019
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu Aug 15 18:45:45 2024
13// Update Count     : 96
14//
15
16#include <fstream.hfa>
17#include <coroutine.hfa>
18
19enum Status { CONT, MSG, ESTX, ELNTH, ECRC };
20
21coroutine Driver {
22        Status status;
23        char * msg, byte;
24}; // Driver
25
26void ?{}( Driver & d, char * m ) { d.msg = m; }                 // constructor
27
28Status next( Driver & d, char b ) with( d ) {                   // called by interrupt handler
29        byte = b; resume( d ); return status;                           // resume coroutine at last suspend
30} // next
31
32void checkCRC( Driver & d, unsigned int sum ) with( d ) {
33        suspend;
34        unsigned short int crc = byte << 8;                                     // sign extension over written
35        suspend;
36        // prevent sign extension for signed char
37        status = (crc | (unsigned char)byte) == sum ? MSG : ECRC;
38} // checkCRC
39
40void main( Driver & d ) with( d ) {
41        enum { STX = '\002', ESC = '\033', ETX = '\003', MaxMsg = 64 };
42  msg: for () {                                                                                 // parse message
43                status = CONT;
44                unsigned int lnth = 0, sum = 0;
45                while ( byte != STX ) suspend;
46          emsg: for () {
47                        suspend;
48                        choose ( byte ) {                                                       // process byte
49                          case STX:
50                                status = ESTX; suspend; continue msg;
51                          case ETX:
52                                break emsg;
53                          case ESC:
54                                suspend;
55                        } // choose
56                        if ( lnth >= MaxMsg ) {                                         // buffer full ?
57                                status = ELNTH; suspend; continue msg;
58                        } // if
59                        msg[lnth++] = byte;
60                        sum += byte;
61                } // for
62                msg[lnth] = '\0';                                                               // terminate string
63                checkCRC( d, sum );                                                             // refactor CRC check
64                suspend;
65        } // for
66} // main
67
68int main() {
69        char msg[65], byte;
70        Driver driver = { msg };
71
72        sin | nlOn;                                                                                     // read newline (all) characters
73        try {
74                for () {                                                                                // read until end of file
75                        sin | byte;                                                                     // read one character
76                        choose( next( driver, byte ) ) {                        // analyse character
77                          case CONT: ;
78                          case MSG: sout | "msg:" | msg;
79                          case ESTX: sout | "STX in message";
80                          case ELNTH: sout | "message too long";
81                          case ECRC: sout | "CRC failure";
82                        } // choose
83                } // for
84        } catch( end_of_file * ) {
85        } // try
86} // main
87
88// Local Variables: //
89// compile-command: "cfa -g -Wall -Wextra devicedriver.cfa" //
90// End: //
Note: See TracBrowser for help on using the repository browser.