fasdf gfaha / Terminal

Terminal.cpp

Committer:
UCSBRobotics
Date:
2012-08-03
Revision:
6:4269b879a2af
Parent:
4:4bcb955b81f3
Child:
9:bb92a6ecb668

File content as of revision 6:4269b879a2af:

#include "Terminal.h"
#include "mbed.h"
#include <cctype>
#include <cstring>



Terminal::Terminal(PinName tx, PinName rx, int baudrate) : serial(tx, rx)
{
    // Initialize various values
    numCommands = 0;
    runningCmd = NULL;
    
    // Set up serial connection
    serial.baud(baudrate);
    serial.attach(this, &Terminal::receive, Serial::RxIrq);
    serial.printf("> ");
}



void Terminal::addCommand(const char* cmdString, CmdHandler* (*fpointer)(Terminal*, const char*) )
{
    if (numCommands < NUM_COMMANDS_MAX)
    {
        strncpy(cmdList[numCommands].cmdString, cmdString, INPUT_BUFFER_MAX);
        cmdList[numCommands].cmdString[INPUT_BUFFER_MAX - 1] = '\0'; // Make sure that the command string is null terminated
        cmdList[numCommands].stringLength = strlen(cmdList[numCommands].cmdString);
        cmdList[numCommands].fpointer = fpointer;
        numCommands++;
    }
    else
    {
        serial.printf("error: too many commands");
    }
}



void Terminal::terminateCmd()
{
    if (runningCmd != NULL)
    {
        delete runningCmd;
        runningCmd = NULL;
    }
    
    serial.printf("\n> ");
    inputBuffer[0] = '\0';
}



void Terminal::write(const char* string)
{
    printf("%s", string);
}



void Terminal::receive()
{
    char c = serial.getc();
    
    // Check if a command is currently running
    if (runningCmd == NULL) // No command is currently running
    {
        int len = strlen(inputBuffer);
        
        if (isprint(c))
        {
            if (len < INPUT_BUFFER_MAX - 1)
            {
                inputBuffer[len] = c;
                inputBuffer[len + 1] = '\0';
                serial.putc(c);
            }
        }
        else if (c == '\b' || c == 127) // Backspace
        {
            if (len > 0)
            {
                inputBuffer[len - 1] = '\0';
                serial.printf("\b \b");
            }
        }
        else if (c == '\n')
        {
            serial.putc('\n');
            
            bool matchFound = false;
            
            // Try to match the input string to a command, and call the associated function if a match is found
            for (int i = 0; i < NUM_COMMANDS_MAX; i++)
            {
                if (cmdList[i].stringLength && !strncmp(inputBuffer, cmdList[i].cmdString, cmdList[i].stringLength))
                {
                    runningCmd = cmdList[i].fpointer(this, inputBuffer);
                    matchFound = true;
                    break;
                }
            }
            
            if (matchFound)
            {
                // If the command finishes immediately, it should return null instead of a pointer to a CmdHandler
                if (runningCmd == NULL)
                    terminateCmd();
            }
            else
            {
                // No match was found
                serial.printf("unrecognized command");
            }
        }
    }
    else // A command is running, so pass the character to the CmdHandler
    {
        runningCmd->sendChar(c);
    }
}