///////////////////////////////////// // // Identifiers // int processChar( StatefulString *ss ) { int length = isUnicodeSequenceStart( ss, 0 ); if ( length ) { for ( int i = 0; i < length; i++ ) { ss_getchar( ss ); } return length; } else { ss_getchar( ss ); return 1; } }
int main() { RS232_INFO info; char str[10000]; printf("Enter port [/dev/ttyS0]: "); fgets(str, sizeof(str), stdin); if (strchr(str, '\n')) *strchr(str, '\n') = 0; if (!str[0]) strcpy(str, "/dev/ttyS0"); info.fd = rs232_open(str, 9600, 'N', 8, 1, 0); if (info.fd < 0) { printf("Cannot open ttyS0\n"); return 0; } /* turn on debugging, will go to rs232.log */ rs232(CMD_DEBUG, TRUE); printf("Connected to ttyS0, exit with <ESC>\n"); do { memset(str, 0, sizeof(str)); str[0] = ss_getchar(0); if (str[0] == 27) break; if (str[0] > 0) rs232_puts(&info, str); rs232_gets(&info, str, sizeof(str), "", 10); printf(str); fflush(stdout); } while (1); ss_getchar(TRUE); rs232_exit(&info); return 1; }
///////////////////////////////////// // // Strings // Token *parseString( Tokenizer *tokenizer ) { StatefulString *ss = tokenizer->ss_; assert( isStringStart( ss, 0 ) ); int start, length; StatefulStringPosition pos1, pos2; wchar_t temp; Token *token; length = 0; pos1 = ss->next_position; wchar_t quote = ss_getchar( ss ); start = ss->next_index; // Exclude the quotes while ( ( temp = ss_getchar( ss ) ) != WEOF && !isNewline( temp ) && temp != quote ) { length++; if ( temp == L'\\' ) { ss_getchar( ss ); length++; } } pos2 = ss->next_position; token = token_new( ss_substr( ss, start, length ), length, STRING, pos1, pos2 ); wchar_t *error = malloc( 201 * sizeof( wchar_t ) ); error[ 0 ] = L'\0'; if ( temp == WEOF ) { swprintf( error, 200, L"Encountered end-of-file while parsing a string. Looks like a `%C` is missing.", quote ); } else if ( isNewline( temp ) ) { error = L"Encountered a newline while parsing a string. Strings can only contain newlines if they're properly escaped (e.g. `\\[\\n]`)"; } if ( wcscmp( error, L"" ) != 0 ) { tokenizer_error( tokenizer, error, token ); } else { free( error ); } return token; }
Token *parseNumber( Tokenizer *tokenizer ) { StatefulString *ss = tokenizer->ss_; assert( isNumberStart( ss, 0 ) ); int start, length; StatefulStringPosition pos1, pos2; start = ss->next_index; length = 0; pos1 = ss->next_position; TokenType type = NUMBER; int isFloat = 0; wchar_t temp; while ( isNumeric( ss_peek( ss ) ) || ( ss_peek( ss ) == L'-' && length == 0 ) || ( ss_peek( ss ) == L'.' && !isFloat ) ) { temp = ss_getchar( ss ); if ( temp == L'.' ) { isFloat = 1; } length++; } // Is the number followed by a percentage? if ( ss_peek( ss ) == L'%' ) { ss_getchar( ss ); length++; type = PERCENTAGE; } // Is the number followed by a dimension? else if ( isIdentifierStart( ss, 0 ) ) { while ( isNameChar( ss_peek( ss ) ) ) { ss_getchar( ss ); length++; } type = DIMENSION; } pos2 = ss->next_position; return token_new( ss_substr( ss, start, length ), length, type, pos1, pos2 ); }
///////////////////////////////////// // // #keyword // Token *parseHashkeyword( Tokenizer *tokenizer ) { assert( isHashkeywordStart( tokenizer->ss_, 0 ) ); StatefulStringPosition *start = malloc( sizeof( StatefulStringPosition ) ); memcpy( start, &( ( tokenizer->ss_ )->next_position ), sizeof( StatefulStringPosition ) ); ss_getchar( tokenizer->ss_ ); // Throw away the `#` Token *t = parseName( tokenizer ); t->type = HASHKEYWORD; free( t->start ); t->start = start; return t; }
/////////////////////////////////////////////////////////////////////////// // // Parsing Functions // ///////////////////////////////////// // // Whitespace // Token *parseWhitespace( Tokenizer *tokenizer ) { StatefulString *ss = tokenizer->ss_; assert( isWhitespaceStart( ss, 0 ) ); int start, length; StatefulStringPosition pos1, pos2; start = ss->next_index; length = 0; pos1 = ss->next_position; while ( isWhitespace( ss_peek( ss ) ) ) { ss_getchar( ss ); length++; } pos2 = ss->next_position; return token_new( ss_substr( ss, start, length ), length, WHITESPACE, pos1, pos2 ); }
Token *parseName( Tokenizer *tokenizer ) { StatefulString *ss = tokenizer->ss_; assert( isNameChar( ss_peek( ss ) ) || isUnicodeSequenceStart( ss, 0 ) ); int start, length; StatefulStringPosition pos1, pos2; start = ss->next_index; length = 0; pos1 = ss->next_position; while ( isNameChar( ss_peek( ss ) ) || isUnicodeSequenceStart( ss, 0 ) ) { length += processChar( ss ); } if ( ss_peek( ss ) == L'(' ) { ss_getchar( ss ); length++; } pos2 = ss->next_position; return token_new( ss_substr( ss, start, length ), length, NAME, pos1, pos2 ); }
Token *parseComment( Tokenizer *tokenizer ) { StatefulString *ss = tokenizer->ss_; assert( isCommentStart( ss, 0 ) ); int start, length; StatefulStringPosition pos1, pos2; Token *token; wchar_t *error = malloc( 201 * sizeof( wchar_t ) ); error[ 0 ] = L'\0'; start = ss->next_index; pos1 = ss->next_position; length = 2; TokenType type = COMMENT; ss_getchar( ss ); ss_getchar( ss ); // Throw away `/*` while ( ss_peek( ss ) != WEOF && ( ss_peek( ss ) != L'*' || ss_peekx( ss, 1 ) != L'/' ) ) { length++; if ( ss_getchar( ss ) == L'\\' ) { ss_getchar( ss ); length++; } } if ( ss_peek( ss ) == WEOF ) { swprintf( error, 200, L"Encountered end-of-file while parsing a comment. Probably a forgotten `*/`." ); } else { ss_getchar( ss ); ss_getchar( ss ); // Throw away `*/` length += 2; } // Return the token. pos2 = ss->next_position; token = token_new( ss_substr( ss, start, length ), length, type, pos1, pos2 ); if ( wcscmp( error, L"" ) != 0 ) { tokenizer_error( tokenizer, error, token ); } else { free( error ); } return token; }
Token *parseSGMLComment( Tokenizer *tokenizer ) { StatefulString *ss = tokenizer->ss_; assert( isCDOStart( ss, 0 ) || isCDCStart( ss, 0 ) ); int start, length; StatefulStringPosition pos1, pos2; start = ss->next_index; pos1 = ss->next_position; length = 4; TokenType type = SGML_COMMENT_OPEN; if ( isCDCStart( ss, 0 ) ) { type = SGML_COMMENT_CLOSE; length = 3; } for ( int i = 0; i<length; i++ ) { ss_getchar( ss ); } pos2 = ss->next_position; return token_new( ss_substr( ss, start, length ), length, type, pos1, pos2 ); }
///////////////////////////////////// // // Operators, et al. // Token *parseEverythingElse( Tokenizer *tokenizer ) { StatefulString *ss = tokenizer->ss_; int start, length; StatefulStringPosition pos1, pos2; start = ss->next_index; pos1 = ss->next_position; TokenType type = DELIM; length = 1; wchar_t temp = ss_getchar( ss ); if ( ( temp== L'~' || temp == L'|' || temp == L'*' || temp == L'^' || temp == L'$' ) && ss_peek( ss ) == L'=' ) { ss_getchar( ss ); length++; } if ( length == 1 ) { switch ( temp ) { case L'{': type = CURLY_BRACE_OPEN; break; case L'}': type = CURLY_BRACE_CLOSE; break; case L'[': type = SQUARE_BRACE_OPEN; break; case L']': type = SQUARE_BRACE_CLOSE; break; case L'(': type = PAREN_OPEN; break; case L')': type = PAREN_CLOSE; break; case L':': type = COLON; break; case L';': type = SEMICOLON; break; case L'@': type = AT; break; case L'#': type = HASH; break; case L'%': type = PERCENT; break; case L'.': type = DOT; break; } } else if ( length == 2 ) { switch ( temp ) { case L'~': type = INCLUDES; break; case L'|': type = DASHMATCH; break; case L'^': type = PREFIXMATCH; break; case L'$': type = SUFFIXMATCH; break; case L'*': type = SUBSTRINGMATCH; break; } } pos2 = ss->next_position; return token_new( ss_substr( ss, start, length ), length, type, pos1, pos2 ); }
///////////////////////////////////// // // Url // Token *parseUrl( Tokenizer *tokenizer ) { StatefulString *ss = tokenizer->ss_; assert( isUrlStart( ss, 0 ) ); int start, length; StatefulStringPosition pos1, pos2; Token *token; wchar_t *error = malloc( 201 * sizeof( wchar_t ) ); error[ 0 ] = L'\0'; start = ss->next_index; pos1 = ss->next_position; TokenType type = URL; // Throw away `url(` for ( int i = 0; i<4; i++ ) { ss_getchar( ss ); } length = 4; // Throw away leading whitespace while ( isWhitespaceStart( ss, 0 ) ) { ss_getchar( ss ); length++; } // Process the url if ( isStringStart( ss, 0 ) ) { token = parseString( tokenizer ); length += token->length + 2; // +2 for the quotes if ( token->error != NULL ) { length -= 1; // Error'd strings don't have a trailing quote pos2 = ss->next_position; Token *t = token_new( ss_substr( ss, start, length ), length, type, pos1, pos2 ); t->error = token->error; ( token->error )->token = t; free( token ); return t; } else { free( token ); } } else if ( isUrlChar( ss_peek( ss ) ) || isUnicodeSequenceStart( ss, 0 ) ) { while ( isUrlChar( ss_peek( ss ) ) || isUnicodeSequenceStart( ss, 0 ) ) { length += processChar( ss ); } } else { // ERROR: if ( ss_peek( ss ) == WEOF ) { swprintf( error, 200, L"Encountered end-of-file while parsing a URL." ); } else { swprintf( error, 200, L"Encountered an invalid character (`%C`) while parsing a URL.", ss_peek( ss ) ); } } // Throw away trailing whitespace while ( isWhitespaceStart( ss, 0 ) ) { ss_getchar( ss ); length++; } // Grab the trailing `)` if ( ss_peek( ss ) == L')' ) { ss_getchar( ss ); length++; } else { // ERROR: if ( ss_peek( ss ) == WEOF ) { swprintf( error, 200, L"Encountered end-of-file while parsing a URL. Expected a `)`." ); } else { swprintf( error, 200, L"Encountered an invalid character (`%C`) while parsing a URL. Expected a `)`. Perhaps a typo?", ss_peek( ss ) ); } } // Return the token. pos2 = ss->next_position; token = token_new( ss_substr( ss, start, length ), length, type, pos1, pos2 ); if ( wcscmp( error, L"" ) != 0 ) { tokenizer_error( tokenizer, error, token ); } else { free( error ); } return token; }
int main(int argc, char *argv[]) { BOOL daemon = FALSE; INT status, i, ch; char host_name[HOST_NAME_LENGTH]; char exp_name[NAME_LENGTH]; char *speech_program = SPEECH_PROGRAM; /* get default from environment */ cm_get_environment(host_name, sizeof(host_name), exp_name, sizeof(exp_name)); #ifdef OS_DARWIN strlcpy(mtTalkStr, "afplay $MIDASSYS/utils/notify.wav", sizeof(mtTalkStr)); strlcpy(mtUserStr, "afplay $MIDASSYS/utils/notify.wav", sizeof(mtTalkStr)); #endif /* parse command line parameters */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-' && argv[i][1] == 'D') daemon = TRUE; else if (argv[i][0] == '-') { if (i + 1 >= argc || argv[i + 1][0] == '-') goto usage; if (argv[i][1] == 'e') strcpy(exp_name, argv[++i]); else if (argv[i][1] == 'h') strcpy(host_name, argv[++i]); else if (argv[i][1] == 'c') speech_program = argv[++i]; else if (argv[i][1] == 't') strcpy(mtTalkStr, argv[++i]); else if (argv[i][1] == 'u') strcpy(mtUserStr, argv[++i]); else if (argv[i][1] == 's') shutupTime = atoi(argv[++i]); else { usage: printf ("usage: mlxspeaker [-h Hostname] [-e Experiment] [-c command] [-D] daemon\n"); printf(" [-t mt_talk] Specify the mt_talk alert command\n"); printf(" [-u mt_user] Specify the mt_user alert command\n"); printf(" [-s shut up time] Specify the min time interval between alert [s]\n"); printf(" The -t & -u switch require a command equivalent to:\n"); printf(" '-t play --volume=0.3 file.wav'\n"); printf(" [-c command] Used to start the speech synthesizer,\n"); printf(" which should read text from it's standard input.\n"); printf(" eg: mlxspeaker -c 'festival --tts -'\n\n"); return 0; } } } if (daemon) { printf("Becoming a daemon...\n"); ss_daemon_init(FALSE); } /* Handle SIGPIPE signals generated from errors on the pipe */ signal(SIGPIPE, sigpipehandler); signal(SIGINT, siginthandler); fp = popen(speech_program, "w"); if (fp == NULL) { cm_msg(MERROR, "Speaker", "Unable to start \"%s\": %s\n", speech_program, strerror(errno)); cm_disconnect_experiment(); exit(2); } /* now connect to server */ status = cm_connect_experiment(host_name, exp_name, "Speaker", NULL); if (status != CM_SUCCESS) return 1; cm_msg_register(receive_message); printf("Midas Message Speaker connected to %s. Press \"!\" to exit.\n", host_name[0] ? host_name : "local host"); /* initialize terminal */ ss_getchar(0); do { status = cm_yield(1000); while (ss_kbhit()) { ch = ss_getchar(0); if (ch == -1) ch = getchar(); if (ch == '!') status = RPC_SHUTDOWN; } } while (status != SS_ABORT && status != RPC_SHUTDOWN); /* reset terminal */ ss_getchar(TRUE); pclose(fp); cm_disconnect_experiment(); return 1; }