[Tinyos-beta-commits] CVS: tinyos-1.x/beta/platform/imote2 BluSH.h,
NONE, 1.1 BluSHC.nc, NONE, 1.1 BluSHM.nc, NONE,
1.1 BluSH_AppI.nc, NONE, 1.1 BluSH_types.h, NONE,
1.1 UARTBufferC.nc, NONE, 1.1 UARTBufferM.nc, NONE,
1.1 cmdlinetools.c, NONE, 1.1
Robbie Adler
radler at users.sourceforge.net
Tue Mar 8 16:59:27 PST 2005
Update of /cvsroot/tinyos/tinyos-1.x/beta/platform/imote2
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25268
Added Files:
BluSH.h BluSHC.nc BluSHM.nc BluSH_AppI.nc BluSH_types.h
UARTBufferC.nc UARTBufferM.nc cmdlinetools.c
Log Message:
Initial IM2 support for UART based shell (BluSH). At some point in the future, BluSH should probably become it's own entity, but for now...
--- NEW FILE: BluSH.h ---
// Number of interfaces.
#define __BLUSH_APP_COUNT__ uniqueCount("BluSH")
enum
{
BLUSH_APP_COUNT = __BLUSH_APP_COUNT__
};
--- NEW FILE: BluSHC.nc ---
configuration BluSHC {
provides interface StdControl;
uses interface BluSH_AppI[uint8_t id];
}
implementation {
components
UARTBufferC as UARTBuffer,
//DebugUARTBufferC as UARTBuffer,
BluSHM;
StdControl = BluSHM;
BluSHM.UartControl -> UARTBuffer.Control;
BluSHM.UartSend -> UARTBuffer.SendVarLenPacket;
BluSHM.UartReceive -> UARTBuffer.ReceiveData;
BluSH_AppI = BluSHM;
}
--- NEW FILE: BluSHM.nc ---
module BluSHM {
provides
{
interface StdControl;
}
uses
{
interface StdControl as UartControl;
interface SendVarLenPacket as UartSend;
interface ReceiveData as UartReceive;
interface BluSH_AppI[uint8_t id];
}
}
implementation
{
#include "cmdlinetools.c"
#include "BluSH_types.h"
//#include <stdio.h> something is wrong with stdio.h
#include <stdarg.h>
#ifdef __GNUC__
#define __VALIST __gnuc_va_list
#else
#define __VALIST char*
#endif
int vsnprintf(char *, size_t, const char *, __VALIST) __attribute__ ((C, spontaneous));
#define BLUSH_PROMPT_LENGTH 32
char blush_prompt[ BLUSH_PROMPT_LENGTH ];
// Index 0 is the current command line.
#define BLUSH_HISTORY_LENGTH 4
#define BLUSH_CMDLINE_LENGTH 80
char blush_history[ BLUSH_HISTORY_LENGTH ][ BLUSH_CMDLINE_LENGTH ];
uint16_t blush_cmdline_idx;
uint16_t blush_history_idx;
uint8_t funcIdx;
uint8_t funcIdxInUse;
char funcCmd[ BLUSH_CMDLINE_LENGTH ];
#define MAX_RETURN_STRING 255
// Internal commands: help, ls, prompt, readmem, writemem.
#if 0
void TraceCallback(char *buf, uint16 buflen) __attribute__((C, spontaneous)){
call UartSend.send(buf,buflen);
}
#endif
#define MAX_PRINTF_LEN 400
//void trace(TOS_dbg_mode mode, const char *format, ...) {
void trace(const char *format, ...) __attribute ((C, spontaneous)) {
// if (trace_active(mode))
{
char buf[MAX_PRINTF_LEN+1];
uint16_t buflen;
va_list args;
va_start(args, format);
//if (!(mode & DBG_SIM))
{
buflen=vsnprintf(buf,MAX_PRINTF_LEN,format,args);
//make sure that we're properly terminating our string...
buflen = (buflen>=MAX_PRINTF_LEN) ? MAX_PRINTF_LEN:buflen;
buf[MAX_PRINTF_LEN] = 0;
call UartSend.send(buf,buflen);
}
}
}
command result_t StdControl.init()
{
uint16_t i;
blush_cmdline_idx = 0;
blush_history_idx = 0;
funcIdxInUse = 0;
// Clear history.
for( i = 0; i < BLUSH_HISTORY_LENGTH; i++ )
{
blush_history[i][0] = '\0';
}
// trace_set(DBG_USR1|DBG_USR2|DBG_USR3);
call UartControl.init();
strncpy( blush_prompt, "BluSH>", BLUSH_PROMPT_LENGTH );
return SUCCESS;
}
command result_t StdControl.start()
{
call UartControl.start();
call UartSend.send( "\r\n", strlen("\r\n") );
call UartSend.send( blush_prompt, strlen(blush_prompt) );
return SUCCESS;
}
command result_t StdControl.stop()
{
call UartControl.stop();
return SUCCESS;
}
default command BluSH_result_t BluSH_AppI.getName[uint8_t id](char* buff, uint8_t len )
{
buff[0] = '\0';
return BLUSH_SUCCESS_DONE;
}
default command BluSH_result_t BluSH_AppI.callApp[uint8_t id]( char* cmdBuff, uint8_t cmdLen,
char* resBuff, uint8_t resLen )
{
resBuff[0] = '\0';
return BLUSH_SUCCESS_DONE;
}
task void ls()
{
uint8_t i;
char temp[ BLUSH_CMDLINE_LENGTH ];
for( i = 0; i < BLUSH_APP_COUNT; i++ )
{
call BluSH_AppI.getName[i]( temp, BLUSH_CMDLINE_LENGTH );
call UartSend.send( temp, strlen(temp) );
call UartSend.send( "\r\n", 2 );
}
}
task void help()
{
call UartSend.send( "Blue Shell v1.0 (BluSH)\r\n",
strlen("Blue Shell v1.0 (BluSH)\r\n") );
call UartSend.send( "help - Display this list\r\n",
strlen("help - Display this list\r\n") );
call UartSend.send( "ls - Display all application commands\r\n",
strlen("ls - Display all application commands\r\n") );
call UartSend.send( "history - Display the command history\r\n",
strlen("history - Display the command history\r\n") );
call UartSend.send( "prompt - Allows you to change the prompt\r\n",
strlen("prompt - Allows you to change the prompt\r\n") );
}
task void history()
{
uint16_t hist_idx;
for( hist_idx = BLUSH_HISTORY_LENGTH-1; hist_idx > 0; hist_idx-- )
{
if( blush_history[ hist_idx ][0] != '\0' )
{
call UartSend.send( blush_history[ hist_idx ],
strlen(blush_history[ hist_idx ]) );
call UartSend.send( "\r\n", strlen("\r\n") );
}
}
}
/*
task void prompt()
{
uint16_t frstSpc;
frstSpc = firstSpace( blush_history[0], 0 );
if( frstSpc == 0 )
{
call UartSend.send( "prompt <new prompt string>\r\n",
strlen("prompt <new prompt string>\r\n") );
}
else
{
strncpy( blush_prompt, &(blush_history[0][frstSpc+1]), BLUSH_PROMPT_LENGTH );
}
}
*/
task void printCmdLine()
{
// Print out prompt.
call UartSend.send( blush_prompt, strlen(blush_prompt) );
// Last but not least, null terminate the command line.
blush_history[0][0] = '\0';
blush_cmdline_idx = 0;
blush_history_idx = 0;
}
task void callFunc()
{
char retStr[ MAX_RETURN_STRING ];
call BluSH_AppI.callApp[funcIdx]( funcCmd, BLUSH_CMDLINE_LENGTH,
retStr, MAX_RETURN_STRING );
// Watch out for buffer overflow.
retStr[ MAX_RETURN_STRING - 1 ] = '\0';
call UartSend.send( retStr, strlen(retStr) );
funcIdxInUse = 0;
}
#define UP_ARROW 0x41
#define DOWN_ARROW 0x42
event result_t UartReceive.receive( uint8_t* buff, uint32_t numBytesRead )
{
uint16_t i, hist_idx, cmd_idx;
char temp[ BLUSH_CMDLINE_LENGTH ];
uint8_t frstSpc;
static uint8_t uSpecialChar=0;
for( i = 0; i < numBytesRead; i++ )
{
// Need to look for special characters:
// ENTER is 0x0d
if( buff[i] == 0x0d )
{
// Append \0
blush_history[0][ blush_cmdline_idx ] = '\0';
// Output new line.
call UartSend.send( "\r\n", 2 );
// Get rid of whitespace.
killWhiteSpace( blush_history[0] );
// check if there is anything meaningful
if( blush_history[0][ 0 ] == '\0' )
{
// Do nothing.
post printCmdLine();
}
else
{
// Copy history
for( hist_idx = BLUSH_HISTORY_LENGTH-1; hist_idx > 0; hist_idx-- )
{
// Rollover to 65535 is intentional.
cmd_idx = -1;
do
{
cmd_idx++;
blush_history[ hist_idx ][ cmd_idx ] =
blush_history[ hist_idx-1 ][ cmd_idx ];
}
while( cmd_idx < BLUSH_CMDLINE_LENGTH
&& blush_history[ hist_idx-1 ][ cmd_idx ] != '\0' );
}
// Process cmdline.
// Look for internal commands first, then blush_app commands.
if( 0 == strncmp( "help", blush_history[0], strlen("help") ) )
{
post help();
post printCmdLine();
/*
call UartSend.send( "Blue Shell v1.0 (BluSH) Native Commands\r\n",
strlen("Blue Shell (BluSH) Native Commands\r\n") );
call UartSend.send( "help - Display this list\r\n",
strlen("help - Display this list\r\n") );
call UartSend.send( "ls - Display all application commands\r\n",
strlen("ls - Display all application commands\r\n") );
call UartSend.send( "history - Display the command history\r\n",
strlen("history - Display the command history\r\n") );
call UartSend.send( "prompt - Allows you to change the prompt\r\n",
strlen("prompt - Allows you to change the prompt\r\n") );
*/
}
else if( 0 == strncmp( "ls", blush_history[0], strlen("ls") ) )
{
post ls();
post printCmdLine();
/*
for( i = 0; i < BLUSH_APP_COUNT; i++ )
{
call BluSH_AppI.getName[i]( temp, BLUSH_CMDLINE_LENGTH );
call UartSend.send( temp, strlen(temp) );
call UartSend.send( "\r\n", 2 );
}
*/
}
else if( 0 == strncmp( "prompt", blush_history[0], strlen("prompt") ) )
{
//post prompt();
//post printCmdLine();
frstSpc = firstSpace( blush_history[0], 0 );
if( frstSpc == 0 )
{
call UartSend.send( "prompt <new prompt string>\r\n",
strlen("prompt <new prompt string>\r\n") );
}
else
{
strncpy( blush_prompt, &(blush_history[0][frstSpc+1]), BLUSH_PROMPT_LENGTH );
}
post printCmdLine();
}
else if( 0 == strncmp( "history", blush_history[0], strlen("history") ) )
{
post history();
post printCmdLine();
/*
for( hist_idx = BLUSH_HISTORY_LENGTH-1; hist_idx > 0; hist_idx-- )
{
if( blush_history[ hist_idx ][0] != '\0' )
{
call UartSend.send( blush_history[ hist_idx ],
strlen(blush_history[ hist_idx ]) );
sprintf( temp, "%d", strlen(blush_history[ hist_idx ]) );
//call UartSend.send( temp,
//strlen(temp) );
call UartSend.send( "\r\n", strlen("\r\n") );
}
}
*/
}
else
{
if( funcIdxInUse == 0 )
{
// Loop through app commands.
for( i = 0; i < BLUSH_APP_COUNT; i++ )
{
call BluSH_AppI.getName[i]( temp, BLUSH_CMDLINE_LENGTH );
if( (strncmp( temp,
blush_history[0],
strlen(temp)) == 0)
&& ((blush_history[0][strlen(temp)] == ' ')
|| (blush_history[0][strlen(temp)] == '\0')) )
{
funcIdx = i;
funcIdxInUse = 1;
strcpy( funcCmd, blush_history[0] );
post callFunc();
/*
call BluSH_AppI.callApp[i]( blush_history[0], BLUSH_CMDLINE_LENGTH,
temp2, BLUSH_CMDLINE_LENGTH );
call UartSend.send( temp2, strlen(temp2) );
*/
break;
}
}
if( i == BLUSH_APP_COUNT )
{
call UartSend.send( "Bad command\r\n", strlen("Bad command\r\n") );
}
}
else
{
call UartSend.send( "Shell Busy\r\n",
strlen("Shell Busy\r\n") );
}
post printCmdLine();
}
}
/*
// Print out prompt.
call UartSend.send( blush_prompt, strlen(blush_prompt) );
// Last but not least, null terminate the command line.
blush_history[0][0] = '\0';
blush_cmdline_idx = 0;
blush_history_idx = 0;
*/
}
// CTRL-C
else if( buff[i] == 0x03 )
{
// Discard history.
blush_cmdline_idx = 0;
blush_history_idx = 0;
blush_history[0][0] = '\0';
// print out new line and prompt.
call UartSend.send( "\r\n", 2 );
call UartSend.send( blush_prompt, strlen(blush_prompt) );
}
// TAB is 0x09
else if( buff[i] == 0x09 )
{
// Tab completetion.
// Search through list of available names.
// Ouput correct one, or beep.
for( i = 0; i < BLUSH_APP_COUNT; i++ )
{
call BluSH_AppI.getName[i]( temp, BLUSH_CMDLINE_LENGTH );
if( strncmp( blush_history[0],
temp,
strlen(blush_history[0])) == 0 )
{
call UartSend.send( temp+strlen(blush_history[0]),
strlen(temp)-strlen(blush_history[0]) );
call UartSend.send( " ", 1 );
strcat( blush_history[0], temp+strlen(blush_history[0]) );
strcat( blush_history[0], " " );
blush_cmdline_idx = strlen(temp)+1;
// add NULL.
blush_history[0][blush_cmdline_idx] = '\0';
break;
}
}
if( i >= BLUSH_APP_COUNT )
{
// No match found. Send beep.
call UartSend.send( "\a", 1 );
}
}
// Arror keys.
else if( buff[i] == 0x1b || uSpecialChar!=0 ){
static int special_i=0;
//check to see if the current char is part of the escape sequence
switch(special_i){
case 0:
uSpecialChar=1;
special_i++;
break;
case 1:
if(buff[i]!=0x5b){
uSpecialChar=0;
special_i=0;
//at this point, we know that our escape sequence was invalid, so we should treat
//the current character as a normal character...need to fall through on the outer loop
//at the moment, I'm happy with losing a character if the escape key is pressed
continue;
}
special_i++;
break;
case 2:
uSpecialChar=buff[i];
case 3:
case 4:
case 5:
//pretty much need to assume that these characters are 0's
special_i++;
}
if( special_i == 6 && uSpecialChar == UP_ARROW ){
// Then it is an up arrow.
if( blush_history_idx < BLUSH_HISTORY_LENGTH-1 ){
blush_history_idx++;
// Erase what's currently there.
for( i = 0; i < blush_cmdline_idx; i++ ){
// send backspace space backspace sequenence
call UartSend.send("\b \b", 3 );
}
// Copy history index.
strcpy( blush_history[0], blush_history[ blush_history_idx ] );
call UartSend.send( blush_history[0], strlen(blush_history[0]) );
blush_cmdline_idx = strlen(blush_history[0]);
}
else{
call UartSend.send( "\a", 1 );
}
} // Check for up arrow.
else if( special_i == 6 && uSpecialChar == DOWN_ARROW ){
// Then it is a down arrow.
if( blush_history_idx > 0 ){
blush_history_idx--;
if( blush_history_idx == 0 ){
// Erase what's currently there.
for( i = 0; i < blush_cmdline_idx; i++ ){
// send backspace space backspace sequence
call UartSend.send("\b \b", 3 );
}
blush_cmdline_idx = 0;
blush_history[0][0] = '\0';
}
else{
// Erase what's currently there.
for( i = 0; i < blush_cmdline_idx; i++ ){
// send backspace space backspace sequence
call UartSend.send("\b \b", 3 );
}
// Copy history index.
strcpy( blush_history[0], blush_history[ blush_history_idx ] );
call UartSend.send( blush_history[0], strlen(blush_history[0]) );
blush_cmdline_idx = strlen(blush_history[0]);
}
}
else{
call UartSend.send( "\a", 1 );
}
} // check for down arrow.
if(special_i==6){
special_i=0;
uSpecialChar=0;
}
} // Special char check.
// Backspace
else if( buff[i] == '\b' )
{
if( blush_cmdline_idx > 0 )
{
// Echo the character back.
call UartSend.send( &buff[i], 1 );
// Print a space
call UartSend.send( " ", 1 );
// Echo the character back.
call UartSend.send( &buff[i], 1 );
blush_cmdline_idx--;
blush_history[0][blush_cmdline_idx] = '\0';
}
else
{
call UartSend.send( "\a", 1 );
}
}
else // Normal character.
{
// By this time we know that it's not a special character.
// Copy it into our buffer.
if( blush_cmdline_idx < BLUSH_CMDLINE_LENGTH - 1 )
{
blush_history[0][ blush_cmdline_idx ] = buff[ i ];
blush_cmdline_idx++;
// Put a \0 on the end for safety.
blush_history[0][ blush_cmdline_idx ] = '\0';
// Echo the character back.
call UartSend.send( &buff[i], 1 );
}
else
{
// Send bell back, avoid buffer overflow.
//buff[i] = '\a';
call UartSend.send( "\a", 1 );
}
}
}
return SUCCESS;
}
event result_t UartSend.sendDone(uint8_t* packet, result_t success)
{
// This function does nothing.
return SUCCESS;
}
}
--- NEW FILE: BluSH_AppI.nc ---
/* Blue Shell (BluSH) application (aka module) interface */
includes BluSH_types;
includes BluSH;
interface BluSH_AppI
{
command BluSH_result_t getName( char* buff, uint8_t len );
command BluSH_result_t callApp( char* cmdBuff, uint8_t cmdLen,
char* resBuff, uint8_t resLen );
}
--- NEW FILE: BluSH_types.h ---
enum
{
BLUSH_SUCCESS_DONE = 0,
BLUSH_SUCCESS_NOT_DONE,
BLUSH_FAIL
};
typedef uint8_t BluSH_result_t;
--- NEW FILE: UARTBufferC.nc ---
configuration UARTBufferC {
provides {
interface StdControl as Control;
interface SendVarLenPacket;
interface ReceiveData;
}
}
implementation {
components UARTBufferM, UART;
Control = UARTBufferM;
SendVarLenPacket = UARTBufferM;
ReceiveData = UARTBufferM;
UARTBufferM.ByteComm -> UART;
UARTBufferM.ByteControl -> UART;
}
--- NEW FILE: UARTBufferM.nc ---
/* tab:4
* IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
* downloading, copying, installing or using the software you agree to
* this license. If you do not agree to this license, do not download,
* install, copy or use the software.
*
* Intel Open Source License
*
* Copyright (c) 2002 Intel Corporation
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the Intel Corporation nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*/
/*
* This module maintains a buffer of characters to put on the UART.
* It copies incoming characters into the buffer and streams them out the
* UART as each previous character finishes.
*/
module UARTBufferM {
provides {
interface StdControl as Control;
interface SendVarLenPacket;
interface ReceiveData;
}
uses {
interface ByteComm;
interface StdControl as ByteControl;
}
}
implementation
{
uint32_t Head; // Next entry in the buffer to fill
uint32_t Tail; // Oldest entry in the buffer
// Head == Tail -> buffer is empty
#define NEXT_BUFFER(ent, max) (((ent) >= ((max) - 1)) ? 0 : ((ent) + 1))
#define BUFFER_SIZE 400 // maximum characters buffered in the queue
char Buffer[BUFFER_SIZE]; // circular buffer of characters
bool BytePending; // whether there is a byte sent w/o a
// corresponding sendDone
/*
* Start of StdControl interface
*/
command result_t Control.init() {
Head = 0;
Tail = 0;
atomic {
BytePending = FALSE;
}
return call ByteControl.init();
}
command result_t Control.start() {
return call ByteControl.start();
}
command result_t Control.stop() {
return call ByteControl.stop();
}
/*
* End of StdControl interface
*/
result_t SendNextByte() {
bool busy;
atomic {
busy = (BytePending == TRUE);
}
if (busy) {
return FAIL;
}
if (Head == Tail) return SUCCESS; // buffer is empty
atomic {
BytePending = TRUE;
}
call ByteComm.txByte(Buffer[Tail]);
// if (call ByteComm.txByte(Buffer[Tail]) == FAIL) {
// // UART not enabled
// Tail = Head;
// BytePending = FALSE;
// }
return SUCCESS;
}
/*
* Start of SendVarLenPacket interface
*/
command result_t SendVarLenPacket.send(uint8_t* data, uint8_t length) {
int i, size;
bool not_busy;
// see if there's enough room for this packet
size = (Head < Tail) ? Head + BUFFER_SIZE - Tail : Head - Tail;
if (size + length >= BUFFER_SIZE) return FAIL; // not enough room
// copy incoming bytes to the buffer
for (i = 0; i < length; i++) {
Buffer[Head] = data[i];
Head = NEXT_BUFFER(Head, BUFFER_SIZE);
}
atomic {
not_busy = (BytePending == FALSE);
}
if (not_busy) SendNextByte();
return SUCCESS;
}
default event result_t SendVarLenPacket.sendDone(uint8_t* data, result_t suc) {
return suc;
}
/*
* End of SendVarLenPacket interface
*/
/*
* Start of ByteComm interface
*/
async event result_t ByteComm.txByteReady(bool success) {
atomic {
BytePending = FALSE;
}
if (Head == Tail) return SUCCESS;
Tail = NEXT_BUFFER(Tail, BUFFER_SIZE);
SendNextByte();
return SUCCESS;
}
// this appears to be redundant in the interface with txByteReady
async event result_t ByteComm.txDone() { return SUCCESS; }
async event result_t ByteComm.rxByteReady(uint8_t data, bool error, uint16_t str) {
signal ReceiveData.receive(&data, 1);
return SUCCESS;
}
/*
* End of ByteComm interface
*/
/*
* Start of ReceiveData interface
*/
default event result_t ReceiveData.receive(uint8_t* Data, uint32_t Length) {
return SUCCESS;
}
/*
* End of ReceiveData interface
*/
}
--- NEW FILE: cmdlinetools.c ---
#include <inttypes.h>
// Command line tools.
// Get rid of extra whitespace.
void killWhiteSpace( char* str );
void killWhiteSpace( char* str )
{
uint16_t i, j;
uint16_t startIdx;
// Find first character or line end.
for( i = 0; str[i] != '\0'; i++ )
{
if( str[i] != ' ' )
{
break;
}
}
// Check for end of line.
if( str[i] == '\0' )
{
// Empty string.
str[0] = '\0';
return;
}
startIdx = 0;
while( 1 )
{
// i is the first character of the next word.
// startIdx is where it needs to be copied to.
// Copy line back.
j = startIdx;
while( str[i] != '\0' )
{
str[j] = str[i];
i++;
j++;
}
// Append '\0';
str[j] = '\0';
// Move startIdx to end of word.
for( ; str[startIdx] != ' ' && str[startIdx] != '\0'; startIdx++ )
{}
// See if next word exists;
// Looking for a isalpha.
for( j = startIdx; str[j] != '\0'; j++ )
{
if( str[j] != ' ' )
{
break;
}
}
// See if we fell off the end.
if( str[j] == '\0' )
{
// We're done.
// Copy the \0.
str[startIdx] = '\0';
return;
}
// Copy a space.
str[startIdx] = ' ';
startIdx++;
// j is the start of the next word.
i = j;
}
}
uint16_t firstSpace( char* str, uint16_t start )
{
uint16_t i;
for( i = start; str[i] != '\0'; i++ )
{
if( str[i] == ' ' )
{
return i;
}
}
return start;
}
uint16_t cntArgs( char* str, uint16_t start )
{
uint16_t count, i;
count = i = 0;
// Rollover of i is intentional.
i--;
do
{
i++;
if( str[i] == ' ' || str[i] == '\0' )
{
count++;
}
}
while( str[i] != '\0' );
return count;
}
More information about the Tinyos-beta-commits
mailing list