Shellminator V3.0.1
Simple Terminal
Loading...
Searching...
No Matches
Example 202 Commander Simple Arguments

Handling Command Arguments

Every command-line system eventually faces the challenge of parameterizing commands —at some point, simple standalone commands aren’t enough.

Let’s take the sum command from our previous example. I bet you’ve wondered:
Is there an easier way to parse those two numbers?

Good news—yes, there is! But before we jump in, let’s go over a few key concepts.

Types of Arguments

In general, there are three types of arguments:

  1. Positional – Must appear in a specific order.
  2. Position-independent – Can appear anywhere in the command.
  3. Optional – Can be included but aren’t required.

What’s cool is that these argument types can be mixed. For example, you might require two positional arguments at the start and allow a few optional ones at the end. From an implementation standpoint, optional and non-positional arguments can be handled similarly since their placement is flexible.

Using Positional Arguments in the sum Command

Positional arguments are useful when:

  • The order of operations doesn’t matter or is trivial (e.g., addition, multiplication).
  • There is only one required argument.

Let’s set up positional arguments for our sum function.

First, you need to include the Commander-Arguments package:

#include "Commander-Arguments.hpp"

For each argument, we create an Argument object. The constructor determines the type of argument.

The basic syntax for a positional argument is:

Argument a(args, place);
  • args → The argument list received in the command callback.
  • place → The index of the argument (starting from 0, left to right).

For example, given the command:

sum 10 20
  • The 0th argument is 10.
  • The 1st argument is 20.

After configuring the argument, we need to extract its value. The Commander library supports three data types:

  • int (parseInt())
  • float (parseFloat())
  • string (parseString())

Since we need two integers, we’ll use parseInt(). The parsing functions return true if successful, or false if the argument could not be converted.

Argument a(args, 0);
if (!a.parseInt()) {
// Error handling
return false;
}

Now that we’ve successfully parsed the argument, we need to retrieve its value. Here’s where C++ magic comes into play—don’t worry, it’s simpler than it sounds!

To get the argument value, cast the argument object to the desired type:

Serial.print((int)a);

⚠️ Important: The cast type must match the parsing method you used. Since we used parseInt(), we cast the argument to int.

This method makes it easy to work with positional arguments and helps keep command processing efficient. Stay tuned—we’ll explore non-positional and optional arguments next!

Live Demo

Whole Code

/*
* Created on Aug 10 2020
*
* Copyright (c) 2023 - Daniel Hajnal
* hajnal.daniel96@gmail.com
* This file is part of the Shellminator project.
* Modified 2023.05.13
*/
#include "Shellminator.hpp"
#include "Commander-API.hpp"
#include "Commander-Arguments.hpp"
// We have to create an object from Commander class.
Commander commander;
bool cat_func( char *args, CommandCaller* caller );
bool dog_func( char *args, CommandCaller* caller );
bool sum_func( char *args, CommandCaller* caller );
Commander::systemCommand_t API_tree[] = {
systemCommand( "cat", "Description for cat command.", cat_func ),
systemCommand( "dog", "Description for dog command.", dog_func ),
systemCommand( "sum", "This function sums two number from the argument list.", sum_func )
};
// Create a ShellminatorCommanderInterface object, and initialize it to use Serial
// System init section.
void setup(){
Serial.begin(115200);
// Clear the terminal
shell.clear();
commander.attachDebugChannel( &Serial );
commander.attachTree( API_tree );
commander.init();
shell.attachCommander( &commander );
// Initialize shell object.
shell.begin( "arnold" );
}
// Infinite loop.
void loop(){
// Process the new data.
shell.update();
}
bool cat_func(char *args, CommandCaller* caller ){
caller -> print("Hello from cat function!\r\n");
return true;
}
bool dog_func(char *args, CommandCaller* caller ){
caller -> print("Hello from dog function!\r\n");
return true;
}
bool sum_func(char *args, CommandCaller* caller ){
int sum;
Argument a( args, 0 );
Argument b( args, 1 );
if( !( a.parseInt() && b.parseInt() ) ){
caller -> print( "Argument error! Two numbers required, separated with a blank space.\r\n" );
return false;
}
// Calculate the sum.
sum = (int)a + (int)b;
// Print out the result.
caller -> print( (int)a );
caller -> print( " + " );
caller -> print( (int)b );
caller -> print( " = " );
caller -> println( sum );
return true;
}