Simple embedded shell with runtime pluggable commands.

Dependents:   DataBus2018

Implements a simple unix-like shell for embedded systems with a pluggable command architecture.

SimpleShell.cpp

Committer:
shimniok
Date:
2018-12-02
Revision:
5:8f486f4d29d3
Parent:
4:8b8fa59d0015
Child:
8:41b7274a9753
Child:
10:c3faa7ffd23b

File content as of revision 5:8f486f4d29d3:

#include "SimpleShell.h"
#include <ctype.h>

SimpleShell::SimpleShell()
{
    lookupEnd = 0;
}

void SimpleShell::run()
{
    bool done=false;
    Callback<void()> cb;
    int status; // TODO implement command status return
    
    strcpy(_cwd, "/log");

    printf("Type help for assistance.\n");
    while (!done) {
        printPrompt();
        readCommand();
        if (cmd[0]) { // skip blank command
            if (cb = findCommand()) {
                cb.call();
            } else {
                printf("command <%s> not found\n", cmd);
            }
        }
    }
    puts("exiting shell\n");

    return;
}


void SimpleShell::attach(Callback<void()> cb, char *command) 
{  
    if (lookupEnd < MAXLOOKUP) {
        lookup[lookupEnd].cb = cb;
        lookup[lookupEnd].command = command;
        lookupEnd++;
    }
    
    for (int i=0; i < lookupEnd; i++) {
        printf("%s\n", lookup[i].command);
    }
        
    return;
}


Callback<void()> SimpleShell::findCommand()
{
    Callback<void()> cb=NULL;
    
    for (int i=0; i < lookupEnd; i++) {
        if (strncmp(cmd, lookup[i].command, MAXBUF) == 0) {
            cb = lookup[i].cb;
            break;
        }
    }
    
    return cb;
}


void SimpleShell::printPrompt()
{
    fputc('(', stdout);
    fputs(_cwd, stdout);
    fputs(")# ", stdout);
    
    return;
}


void SimpleShell::readCommand()
{
    int i=0;
    char c;
    bool done = false;
    
    memset(cmd, 0, MAXBUF);
    do {
        cmd[i] = 0;
        c = fgetc(stdin);
        if (c == '\r') { // if return is hit, we're done, don't add \r to cmd
            done = true;
        } else if (i < MAXBUF-1) {
            if (c == 0x7f || c == '\b') { // backspace or delete
                if (i > 0) { // if we're at the beginning, do nothing
                    i--;
                    fputs("\b \b", stdout);

                }
            } else {
                fputc(c, stdout);
                cmd[i++] = c;
            }
        }
    } while (!done);
    fputc('\n', stdout);

    // chomp
    for (int j=i; j >= 0; j--) {
        if (isspace(cmd[j])) {
            cmd[j] = '\0';
        }
    }

    return;
}