//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2015 Authors and OPENCORES.ORG ////
|
//// Copyright (C) 2015 Authors and OPENCORES.ORG ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <string.h>
|
#include <string.h>
|
#include <unistd.h>
|
#include <unistd.h>
|
|
|
#include "sys_cmd.h"
|
#include "sys_cmd.h"
|
#include "sys_error.h"
|
#include "sys_error.h"
|
|
|
|
|
|
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
|
void clear_screen(void)
|
|
{
|
|
PRINTF_MACRO("\033[H\033[J");
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------*/
|
#ifdef ANSI_ESCAPE_CODE
|
#ifdef ANSI_ESCAPE_CODE
|
#define ASCII_ESC '\x1b'
|
#define ASCII_ESC '\x1b'
|
|
|
static void send_csi( char c )
|
static void send_csi(char c)
|
{
|
{
|
putchar( ASCII_ESC );
|
putchar(ASCII_ESC);
|
putchar( '[' );
|
putchar('[');
|
putchar( c );
|
putchar(c);
|
}
|
}
|
#else
|
#else
|
static void send_csi( char c ) {};
|
static void send_csi(char c) {};
|
#endif
|
#endif
|
|
|
|
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
static char *cli_edit_buffer( char *in_buffer, char *out_buffer, unsigned int line_length )
|
static char *cli_edit_buffer(char *in_buffer, char *out_buffer, unsigned int line_length)
|
{
|
{
|
static char *out_ptr;
|
static char *out_ptr;
|
static char *begin_ptr;
|
static char *begin_ptr;
|
static char *end_ptr;
|
static char *end_ptr;
|
|
|
#ifdef ANSI_ESCAPE_CODE
|
#ifdef ANSI_ESCAPE_CODE
|
static char prev_char;
|
static char prev_char;
|
static unsigned int csi;
|
static unsigned int csi;
|
#endif
|
#endif
|
|
|
unsigned int i;
|
unsigned int i;
|
|
|
if( out_buffer != NULL )
|
if(out_buffer != NULL)
|
{
|
{
|
out_ptr = out_buffer;
|
out_ptr = out_buffer;
|
begin_ptr = out_buffer;
|
begin_ptr = out_buffer;
|
end_ptr = out_buffer + INPUT_LINE_LENGTH;
|
end_ptr = out_buffer + INPUT_LINE_LENGTH;
|
|
|
#ifdef ANSI_ESCAPE_CODE
|
#ifdef ANSI_ESCAPE_CODE
|
prev_char = 0;
|
prev_char = 0;
|
csi = 0;
|
csi = 0;
|
#endif
|
#endif
|
}
|
}
|
|
|
for( i = 0 ; i < line_length ; i++ )
|
for(i = 0 ; i < line_length ; i++)
|
{
|
{
|
|
|
if( out_ptr >= end_ptr )
|
if(out_ptr >= end_ptr)
|
{
|
{
|
*end_ptr = '\0';
|
*end_ptr = '\0';
|
return( NULL );
|
return(NULL);
|
}
|
}
|
|
|
if( out_ptr < begin_ptr )
|
if(out_ptr < begin_ptr)
|
sys_error_fatal( FATAL_ERROR_CLI );
|
sys_error_fatal(FATAL_ERROR_CLI);
|
|
|
switch( in_buffer[i] )
|
switch(in_buffer[i])
|
{
|
{
|
case '\0':
|
case '\0':
|
return( NULL );
|
return(NULL);
|
break;
|
break;
|
|
|
case '\n':
|
case '\n':
|
*out_ptr = '\0';
|
*out_ptr = '\0';
|
return( NULL );
|
return(NULL);
|
break;
|
break;
|
|
|
case '\r':
|
case '\r':
|
*out_ptr = '\0';
|
*out_ptr = '\0';
|
return( NULL );
|
return(NULL);
|
break;
|
break;
|
|
|
case '\b':
|
case '\b':
|
if( out_ptr != begin_ptr )
|
if(out_ptr != begin_ptr)
|
{
|
{
|
send_csi( 'P' );
|
send_csi('P');
|
out_ptr--;
|
out_ptr--;
|
} else
|
} else
|
{
|
{
|
putchar( ' ' );
|
putchar(' ');
|
send_csi( '\a' );
|
send_csi('\a');
|
}
|
}
|
break;
|
break;
|
|
|
#ifdef ANSI_ESCAPE_CODE
|
#ifdef ANSI_ESCAPE_CODE
|
case ASCII_ESC:
|
case ASCII_ESC:
|
break;
|
break;
|
|
|
case '[':
|
case '[':
|
if( prev_char == ASCII_ESC )
|
if(prev_char == ASCII_ESC)
|
{
|
{
|
csi = 1;
|
csi = 1;
|
} else
|
} else
|
{
|
{
|
*out_ptr = in_buffer[i];
|
*out_ptr = in_buffer[i];
|
out_ptr++;
|
out_ptr++;
|
}
|
}
|
break;
|
break;
|
|
|
case 'A':
|
case 'A':
|
if( csi )
|
if(csi)
|
{
|
{
|
send_csi( 'B' );
|
send_csi('B');
|
send_csi( '\a' );
|
send_csi('\a');
|
|
|
csi = 0;
|
csi = 0;
|
} else
|
} else
|
{
|
{
|
*out_ptr = in_buffer[i];
|
*out_ptr = in_buffer[i];
|
out_ptr++;
|
out_ptr++;
|
}
|
}
|
break;
|
break;
|
|
|
case 'B':
|
case 'B':
|
if( csi == 0 )
|
if(csi == 0)
|
{
|
{
|
*out_ptr = in_buffer[i];
|
*out_ptr = in_buffer[i];
|
out_ptr++;
|
out_ptr++;
|
}
|
}
|
break;
|
break;
|
|
|
case 'C':
|
case 'C':
|
if( csi )
|
if(csi)
|
{
|
{
|
send_csi( 'D' );
|
send_csi('D');
|
send_csi( '\a' );
|
send_csi('\a');
|
|
|
csi = 0;
|
csi = 0;
|
} else
|
} else
|
{
|
{
|
*out_ptr = in_buffer[i];
|
*out_ptr = in_buffer[i];
|
out_ptr++;
|
out_ptr++;
|
}
|
}
|
break;
|
break;
|
|
|
case 'D':
|
case 'D':
|
if( csi )
|
if(csi)
|
{
|
{
|
send_csi( 'C' );
|
send_csi('C');
|
send_csi( '\a' );
|
send_csi('\a');
|
|
|
csi = 0;
|
csi = 0;
|
} else
|
} else
|
{
|
{
|
*out_ptr = in_buffer[i];
|
*out_ptr = in_buffer[i];
|
out_ptr++;
|
out_ptr++;
|
}
|
}
|
break;
|
break;
|
#endif
|
#endif
|
|
|
default:
|
default:
|
*out_ptr = in_buffer[i];
|
*out_ptr = in_buffer[i];
|
out_ptr++;
|
out_ptr++;
|
break;
|
break;
|
}
|
}
|
|
|
#ifdef ANSI_ESCAPE_CODE
|
#ifdef ANSI_ESCAPE_CODE
|
prev_char = in_buffer[i];
|
prev_char = in_buffer[i];
|
#endif
|
#endif
|
}
|
}
|
|
|
return( out_ptr );
|
return(out_ptr);
|
}
|
}
|
|
|
|
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
void sys_cli_task( void )
|
void sys_cli_task(void)
|
{
|
{
|
char last_return_value = EXIT_SUCCESS;
|
char last_return_value = EXIT_SUCCESS;
|
char in_buffer[INPUT_LINE_LENGTH + 1];
|
char in_buffer[INPUT_LINE_LENGTH + 1];
|
char out_buffer[INPUT_LINE_LENGTH + 1];
|
char out_buffer[INPUT_LINE_LENGTH + 1];
|
char *cli_ptr;
|
char *cli_ptr;
|
struct cli_cmd_tab_t cmd_to_check = { "", NULL, NULL };
|
struct cli_cmd_tab_t cmd_to_check = { "", NULL, NULL };
|
unsigned char cli_argc;
|
unsigned char cli_argc;
|
char *cli_argv[MAX_CLI_ARGC];
|
char *cli_argv[MAX_CLI_ARGC];
|
struct cli_cmd_tab_t *cli_cmd;
|
struct cli_cmd_tab_t *cli_cmd;
|
unsigned int bytes_read;
|
unsigned int bytes_read;
|
|
|
cli_init();
|
cli_init();
|
|
|
PRINTF_MACRO( "\r\n" );
|
PRINTF_MACRO("\r\n");
|
|
|
for( ;; )
|
for(;;)
|
{
|
{
|
PRINTF_MACRO( "%d > ", last_return_value );
|
PRINTF_MACRO("%d > ", last_return_value);
|
|
|
cli_argc = 0;
|
cli_argc = 0;
|
last_return_value = EXIT_SUCCESS;
|
last_return_value = EXIT_SUCCESS;
|
|
|
bytes_read = (unsigned int)read( STDIN_FILENO, (void *)in_buffer, sizeof(in_buffer) );
|
bytes_read = (unsigned int)read(STDIN_FILENO, (void *)in_buffer, sizeof(in_buffer));
|
cli_ptr = cli_edit_buffer( in_buffer, out_buffer, bytes_read );
|
cli_ptr = cli_edit_buffer(in_buffer, out_buffer, bytes_read);
|
|
|
while( cli_ptr != NULL )
|
while(cli_ptr != NULL)
|
{
|
{
|
bytes_read = (unsigned int)read( STDIN_FILENO, (void *)in_buffer, sizeof(in_buffer) );
|
bytes_read = (unsigned int)read(STDIN_FILENO, (void *)in_buffer, sizeof(in_buffer));
|
cli_ptr = cli_edit_buffer( in_buffer, NULL, bytes_read );
|
cli_ptr = cli_edit_buffer(in_buffer, NULL, bytes_read);
|
}
|
}
|
|
|
if( out_buffer[0] == '\0' )
|
if( out_buffer[0] == '\0' )
|
{
|
|
PRINTF_MACRO( " NULL String! Command ignored\r\n" );
|
|
last_return_value = EXIT_FAILURE;
|
last_return_value = EXIT_FAILURE;
|
}
|
|
|
|
while( last_return_value != EXIT_FAILURE )
|
while(last_return_value != EXIT_FAILURE)
|
{
|
{
|
cli_ptr = strtok( out_buffer, " \t" );
|
cli_ptr = strtok(out_buffer, " \t");
|
|
|
strncpy( cmd_to_check.cmd, out_buffer, MAX_CMD_LENGTH );
|
strncpy(cmd_to_check.cmd, out_buffer, MAX_CMD_LENGTH);
|
cli_cmd = cli_find_command( &cmd_to_check );
|
cli_cmd = cli_find_command(&cmd_to_check);
|
|
|
if ( cli_cmd == NULL )
|
if (cli_cmd == NULL)
|
{
|
{
|
PRINTF_MACRO( "\r\n Command not found!\r\n" );
|
PRINTF_MACRO("\r\n Command not found!\r\n");
|
last_return_value = EXIT_FAILURE;
|
last_return_value = EXIT_FAILURE;
|
break;
|
break;
|
}
|
}
|
|
|
if( cli_ptr == NULL )
|
if(cli_ptr == NULL)
|
{
|
{
|
cli_argv[cli_argc] = out_buffer;
|
cli_argv[cli_argc] = out_buffer;
|
cli_argc++;
|
cli_argc++;
|
} else
|
} else
|
{
|
{
|
while( cli_ptr != NULL )
|
while(cli_ptr != NULL)
|
{
|
{
|
cli_argv[cli_argc] = cli_ptr;
|
cli_argv[cli_argc] = cli_ptr;
|
cli_argc++;
|
cli_argc++;
|
|
|
cli_ptr = strtok( NULL, " \t" );
|
cli_ptr = strtok(NULL, " \t");
|
}
|
}
|
}
|
}
|
|
|
PRINTF_MACRO( "\r\n" );
|
PRINTF_MACRO("\r\n");
|
|
|
last_return_value = cli_cmd->func( cli_argc, (const char **)cli_argv );
|
last_return_value = cli_cmd->func(cli_argc, (const char **)cli_argv);
|
break;
|
break;
|
}
|
}
|
|
|
}
|
}
|
}
|
}
|
|
|
|
|