Skip to content
Snippets Groups Projects
cli.cpp 3.11 KiB
Newer Older

#include "cli.h"

void Cli::resetNextWord ()
{
    _currentWordIndex = -1;
    _previousWordLength = 0;
}

const char* Cli::findNextWord ()
{
    if (_currentWordIndex >= 0)
        // skip current word
        while (_currentWordIndex < (int)_currentInput.length())
        {
            if (_currentInput[_currentWordIndex] == 32)
                break;
            _currentWordIndex++;
        }
    else
        _currentWordIndex = 0;
    
    size_t _previousWordLength = 0;
    // skip spaces
    while (_currentWordIndex < (int)_currentInput.length())
    {
        if (_currentInput[_currentWordIndex] != 32)
            break;
        _currentWordIndex++;
        _previousWordLength++;
    }
    
    const char* ret = _currentWordIndex < (int)_currentInput.length()? _currentInput.c_str() + _currentWordIndex: nullptr;
    //if (ret)
    //    Serial.printf("# found new start of word '%s'\n", ret);
    return ret;
}

void Cli::copyNextToTemp ()
{
    findNextWord();
    int start = _currentWordIndex;
    findNextWord();
    if (start < _currentWordIndex)
        _temp = _currentInput.substring(start, _currentWordIndex);
    else
        _temp.clear();
}

bool Cli::kw (const __FlashStringHelper* keyWord, const char* input)
{
    // return true if input matches keyWord
    auto len = strlen_P((PGM_P)keyWord);
    return len && strncasecmp_P((PGM_P)keyWord, input, len) == 0;
}

bool Cli::kw (const __FlashStringHelper* keyWord)
{
    return kw(keyWord, _currentInput.c_str() + _currentWordIndex);
}

void Cli::syntax ()
{
    syntax(_currentInput.c_str() + _currentWordIndex);
}

void Cli::syntaxFull ()
{
    syntax((const char*)nullptr);
}

void Cli::syntax (const __FlashStringHelper* cmd)
{
    syntax((PGM_P)cmd);
}

void Cli::syntax (const char* cmd)
{
    if (!cmd || kw(F("AT"), cmd))   Serial.printf("# CLI: AT -> OK\n");
    if (!cmd || kw(F("HELP"), cmd)) Serial.printf("# CLI: HELP [CMD]\n");
    if (!cmd || kw(F("RAT"), cmd))  Serial.printf("# CLI: RAT [ C | I ] [ <rate> [ <unit>(UM/MM/UH/MH) ] ]\n");
    if (!cmd || kw(F("VOL"), cmd))  Serial.printf("# CLI: VOL [ <vol> | <unit>(UL/ML) ]\n");
}

void Cli::loop (Stream& input)
{
    while (true)
    {
        if (!input.available())
            return;
        int c = input.read();
        if (c == 13)
            break;
        if (c >= 32 && c <= 127)
            _currentInput += (char)c;
    }
    
    resetNextWord();
    
    if (findNextWord())
    {
        if (kw(F("AT")))
        {
            Serial.printf("OK\n");
        }
        else if (kw(F("HELP")))
        {
            copyNextToTemp();
            if (_temp.length())
                syntax(_temp.c_str());
            else
                syntaxFull();
        }
        else if (kw(F("RAT")))
        {
            copyNextToTemp();
        }
        else if (kw(F("VOL")))
        {
        }
        else
        {
            Serial.printf("# CLI: invalid command '%s'\n", _currentInput.c_str() + _currentWordIndex);
        }
    }
    
    if (findNextWord())
        Serial.printf("# CLI: garbage at end of line: '%s'\n", _currentInput.c_str() + _currentWordIndex);
    resetNextWord();
    _currentInput.clear();
}