Ignore:
Timestamp:
Feb 13, 2016, 2:22:49 PM (9 years ago)
Author:
alain
Message:

Improve the shell:

  • introduce support for the LEFT / RIGHT / UP / DOWN arrows in the command editor.
  • Introduce a commands registration buffer (128 commands depth).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/applications/shell/shell.c

    r784 r789  
    1212#include "string.h"
    1313
    14 #define BUF_SIZE    (256)        // buffer for one command
     14#define MAX_SIZE    (128)        // max number of characters in one command
     15#define LOG_DEPTH   (128)        // max number of commands in log
    1516#define MAX_ARGS    (32)         // max number of arguments in a command
    1617#define FIFO_SIZE   (1024)       // FIFO depth for recursive ls
    1718
     19////////////////////////////////////////////////////////////////////////////////
     20//       Global Variables
     21////////////////////////////////////////////////////////////////////////////////
     22
     23char         log_buf[LOG_DEPTH][MAX_SIZE];   // registered command strings
     24unsigned int log_count[LOG_DEPTH];           // registered command lengths
     25unsigned int ptw;                            // write pointer in log
     26unsigned int ptr;                            // read pointer in log
    1827
    1928struct command_t
     
    2433};
    2534
     35// this array initialised afer commands definition
     36struct command_t cmd[];
     37
    2638////////////////////////////////////////////////////////////////////////////////
    27 //  Shell  Commands
     39//       Shell  Commands
    2840////////////////////////////////////////////////////////////////////////////////
    2941
    30 struct command_t cmd[];
     42/////////////////////////////////////////////
     43static void cmd_cat(int argc, char** argv)
     44{
     45    if (argc != 2)
     46    {
     47        giet_tty_printf("  usage : cat pathname \n");
     48        return;
     49    }
     50
     51    unsigned int     x,y,p;          // processor coordinates
     52    unsigned int     fd;             // file descriptor
     53    fat_file_info_t  info;           // file info
     54    unsigned int     size;           // buffer size (file_size + 1)
     55    unsigned int     bytes;          // number of bytes to be mapped 
     56    char*            buf = NULL;     // temporary buffer
     57
     58    // get processor coordinates
     59    giet_proc_xyp( &x , &y , &p );
     60   
     61    // open the file to display   
     62    fd = giet_fat_open( argv[1] , 0 );
     63    if (fd < 0)
     64    {
     65        giet_tty_printf("  error : cannot open %s\n", argv[1]);
     66        goto exit;
     67    }
     68
     69    // get file size
     70    giet_fat_file_info( fd, &info );
     71    if ( info.is_dir )
     72    {
     73        giet_tty_printf("  error : %s is a directory\n", argv[1] );
     74        goto exit;
     75    }
     76    size = info.size; 
     77
     78    // extend size to 4 Kbytes boundary if required
     79    if ( (size+1) & 0xFFF)  bytes = (size & 0xFFFFF000) + 0x1000;
     80    else                    bytes = size + 1;
     81
     82    // map local buffer to Cache_file
     83    buf = giet_fat_mmap( NULL,
     84                         bytes,
     85                         MAP_PROT_READ | MAP_PROT_WRITE,
     86                         MAP_SHARED,
     87                         fd,
     88                         0 );
     89    if ( buf == NULL )
     90    {
     91        giet_tty_printf("  error : cannot map %s\n", argv[1] );
     92        goto exit;
     93    }
     94
     95    // set terminating '0'
     96    buf[size] = 0;
     97
     98    // display the file content
     99    giet_tty_printf("%s", buf );
     100
     101exit:
     102    if ( fd >= 0 )     giet_fat_close( fd );
     103    if ( buf != NULL ) giet_fat_munmap( buf , bytes );
     104}  // end cmd_cat()
     105
     106/////////////////////////////////////////////
     107static void cmd_context(int argc, char** argv)
     108{
     109    if (argc < 3)
     110    {
     111        giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
     112        return;
     113    }
     114
     115    giet_pthread_control( THREAD_CMD_CONTEXT , argv[1] , argv[2] );
     116}  // end cmd_context()
     117
     118/////////////////////////////////////////
     119static void cmd_cp(int argc, char** argv)
     120{
     121    if (argc < 3)
     122    {
     123        giet_tty_printf("  usage : cp src_pathname dst_pathname>\n");
     124        return;
     125    }
     126
     127    char buf[1024];
     128    int src_fd = -1;
     129    int dst_fd = -1;
     130    fat_file_info_t info;
     131    int size;
     132    int i;
     133
     134    src_fd = giet_fat_open( argv[1] , O_RDONLY );
     135    if (src_fd < 0)
     136    {
     137        giet_tty_printf("  error : cannot open %s / err = %d\n", argv[1], src_fd);
     138        goto exit;
     139    }
     140
     141    giet_fat_file_info(src_fd, &info);
     142
     143    if (info.is_dir)
     144    {
     145        giet_tty_printf("  error : %s is a directory\n", argv[1] );
     146        goto exit;
     147    }
     148
     149    size = info.size;
     150
     151    dst_fd = giet_fat_open( argv[2] , O_CREAT | O_TRUNC);
     152
     153    if (dst_fd < 0)
     154    {
     155        giet_tty_printf("  error : cannot open %s / err = %d\n", argv[2], dst_fd);
     156        goto exit;
     157    }
     158
     159    giet_fat_file_info(dst_fd, &info);
     160
     161    if (info.is_dir)
     162    {
     163        giet_tty_printf("  error : %s is a directory\n", argv[2] );  // TODO
     164        goto exit;
     165    }
     166
     167    i = 0;
     168    while (i < size)
     169    {
     170        int len = (size - i < 1024 ? size - i : 1024);
     171        int wlen;
     172
     173        len = giet_fat_read(src_fd, &buf, len);
     174        wlen = giet_fat_write(dst_fd, &buf, len);
     175        if (wlen != len)
     176        {
     177            giet_tty_printf("  error : cannot write on device\n");
     178            goto exit;
     179        }
     180        i += len;
     181    }
     182
     183exit:
     184    if (src_fd >= 0)
     185        giet_fat_close(src_fd);
     186    if (dst_fd >= 0)
     187        giet_fat_close(dst_fd);
     188}  // end cmd_cp()
     189
     190///////////////////////////////////////////
     191static void cmd_dump(int argc, char** argv)
     192{
     193    if ((argc == 2) && (strcmp( argv[1] , "-bs" ) == 0))
     194    {
     195        giet_fat_dump( DUMP_BS , NULL , 0 );
     196    }
     197    else if ((argc == 2) && (strcmp( argv[1] , "-fs" ) == 0))
     198    {
     199        giet_fat_dump( DUMP_FS , NULL , 0 );
     200    }
     201    else if ((argc == 3) && (strcmp( argv[1] , "-fat" ) == 0))
     202    {
     203        giet_fat_dump( DUMP_FAT , NULL , atoi( argv[2] ) );
     204    }
     205    else if ((argc == 4) && (strcmp( argv[1] , "-file" ) == 0))
     206    {
     207        giet_fat_dump( DUMP_FILE , argv[2] , atoi( argv[3] ) );
     208    }
     209    else if ((argc == 4) && (strcmp( argv[1] , "-dir" ) == 0))
     210    {
     211        giet_fat_dump( DUMP_DIR , argv[2] , atoi( argv[3] ) );
     212    }
     213    else
     214    {
     215        giet_tty_printf("  usage : dump [-bs] [-fs] [-fat block] "
     216                        "[-file pathname block] [-dir pathname block]\n");
     217        return;
     218    }
     219}  // end cmd_dump()
     220
     221///////////////////////////////////////////
     222static void cmd_exec(int argc, char **argv)
     223{
     224    if (argc < 2)
     225    {
     226        giet_tty_printf("  usage : %s vspace_name\n", argv[0]);
     227        return;
     228    }
     229
     230    int ret = giet_exec_application(argv[1]);
     231    if ( ret == -1 )
     232    {
     233        giet_tty_printf("  error : %s not found\n", argv[1] );
     234    }
     235}  // end cmd_exec()
    31236
    32237///////////////////////////////////////////
     
    41246        giet_tty_printf("\t%s\t : %s\n", cmd[i].name , cmd[i].desc );
    42247    }
    43 }
     248}  // end cmd_help()
    44249
    45250///////////////////////////////////////////
    46 static void cmd_time(int argc, char** argv)
    47 {
    48     giet_tty_printf(" cycle = %d\n", giet_proctime());
    49 }
    50 
     251static void cmd_kill(int argc, char **argv)
     252{
     253    if (argc < 2)
     254    {
     255        giet_tty_printf("  usage : %s vspace_name\n", argv[0]);
     256        return;
     257    }
     258
     259    int ret = giet_kill_application(argv[1]);
     260    if ( ret == -1 )
     261    {
     262        giet_tty_printf("  error : %s not found\n", argv[1] );
     263    }
     264    if ( ret == -2 )
     265    {
     266        giet_tty_printf("  error : %s cannot be killed\n", argv[1] );
     267    }
     268}  // end cmd_kill()
     269
     270///////////////////////////////////////////
     271static void cmd_log( int argc, char** argv)
     272{
     273    giet_tty_printf("--- registered commands ---\n");
     274    unsigned int i;
     275    for ( i = 0 ; i < LOG_DEPTH ; i++ )
     276    {
     277        giet_tty_printf(" - %d\t: %s\n", i , &log_buf[i][0] );
     278    }
     279}  // end cmd_log()
    51280
    52281/////////////////////////////////////////
     
    100329
    101330        // display directory pathname
    102         giet_tty_printf("*** %s ***\n", paths[ptr] );
     331        giet_tty_printf("--- %s ---\n", paths[ptr] );
    103332
    104333        // loop on directory entries
     
    165394        giet_tty_printf("  error : cannot create directory %s / err = %d\n", argv[1], ret);
    166395    }
    167 }
     396}  // end cmd_mkdir()
    168397
    169398/////////////////////////////////////////
    170 static void cmd_cp(int argc, char** argv)
     399static void cmd_mv(int argc, char **argv)
    171400{
    172401    if (argc < 3)
    173402    {
    174         giet_tty_printf("  usage : cp src_pathname dst_pathname>\n");
    175         return;
    176     }
    177 
    178     char buf[1024];
    179     int src_fd = -1;
    180     int dst_fd = -1;
    181     fat_file_info_t info;
    182     int size;
    183     int i;
    184 
    185     src_fd = giet_fat_open( argv[1] , O_RDONLY );
    186     if (src_fd < 0)
    187     {
    188         giet_tty_printf("  error : cannot open %s / err = %d\n", argv[1], src_fd);
    189         goto exit;
    190     }
    191 
    192     giet_fat_file_info(src_fd, &info);
    193 
    194     if (info.is_dir)
    195     {
    196         giet_tty_printf("  error : %s is a directory\n", argv[1] );
    197         goto exit;
    198     }
    199 
    200     size = info.size;
    201 
    202     dst_fd = giet_fat_open( argv[2] , O_CREAT | O_TRUNC);
    203 
    204     if (dst_fd < 0)
    205     {
    206         giet_tty_printf("  error : cannot open %s / err = %d\n", argv[2], dst_fd);
    207         goto exit;
    208     }
    209 
    210     giet_fat_file_info(dst_fd, &info);
    211 
    212     if (info.is_dir)
    213     {
    214         giet_tty_printf("  error : %s is a directory\n", argv[2] );  // TODO
    215         goto exit;
    216     }
    217 
    218     i = 0;
    219     while (i < size)
    220     {
    221         int len = (size - i < 1024 ? size - i : 1024);
    222         int wlen;
    223 
    224         len = giet_fat_read(src_fd, &buf, len);
    225         wlen = giet_fat_write(dst_fd, &buf, len);
    226         if (wlen != len)
    227         {
    228             giet_tty_printf("  error : cannot write on device\n");
    229             goto exit;
    230         }
    231         i += len;
    232     }
    233 
    234 exit:
    235     if (src_fd >= 0)
    236         giet_fat_close(src_fd);
    237     if (dst_fd >= 0)
    238         giet_fat_close(dst_fd);
    239 }
     403        giet_tty_printf("  usage : %s src_pathname dst_pathname\n", argv[0]);
     404        return;
     405    }
     406
     407    int ret = giet_fat_rename(argv[1], argv[2]);
     408    if (ret < 0)
     409    {
     410        giet_tty_printf("error : cannot move %s to %s / err = %d\n", argv[1], argv[2], ret );
     411    }
     412}  // end cmd_mv()
     413
     414////////////////////////////////////////////
     415static void cmd_pause(int argc, char** argv)
     416{
     417    if (argc < 3)
     418    {
     419        giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
     420        return;
     421    }
     422
     423    giet_pthread_control( THREAD_CMD_PAUSE , argv[1] , argv[2] );
     424}  // end cmd_pause()
     425
     426/////////////////////////////////////////
     427static void cmd_ps(int argc, char** argv)
     428{
     429    if (argc == 1)
     430    {
     431        giet_applications_status( NULL );
     432    }
     433    else
     434    {
     435        giet_applications_status( argv[1] );
     436    }
     437}  // end cmd_ps()
     438
     439/////////////////////////////////////////////
     440static void cmd_resume(int argc, char** argv)
     441{
     442    if (argc < 3)
     443    {
     444        giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
     445        return;
     446    }
     447
     448    giet_pthread_control( THREAD_CMD_RESUME , argv[1] , argv[2] );
     449}  // end cmd_resume()
    240450
    241451/////////////////////////////////////////
     
    254464        giet_tty_printf("  error : cannot remove %s / err = %d\n", argv[1], ret );
    255465    }
    256 }
     466}  // end cmd_rm()
    257467
    258468////////////////////////////////////////////
     
    270480        giet_tty_printf("  error : cannot remove %s / err = %d\n", argv[1], ret );
    271481    }
     482}  // end cmd_rmdir()
     483
     484///////////////////////////////////////////
     485static void cmd_time(int argc, char** argv)
     486{
     487    giet_tty_printf(" cycle = %d\n", giet_proctime());
    272488}
    273489
    274 /////////////////////////////////////////
    275 static void cmd_mv(int argc, char **argv)
    276 {
    277     if (argc < 3)
    278     {
    279         giet_tty_printf("  usage : %s src_pathname dst_pathname\n", argv[0]);
    280         return;
    281     }
    282 
    283     int ret = giet_fat_rename(argv[1], argv[2]);
    284     if (ret < 0)
    285     {
    286         giet_tty_printf("error : cannot move %s to %s / err = %d\n", argv[1], argv[2], ret );
    287     }
    288 }
    289 
    290 ///////////////////////////////////////////
    291 static void cmd_exec(int argc, char **argv)
    292 {
    293     if (argc < 2)
    294     {
    295         giet_tty_printf("  usage : %s vspace_name\n", argv[0]);
    296         return;
    297     }
    298 
    299     int ret = giet_exec_application(argv[1]);
    300     if ( ret == -1 )
    301     {
    302         giet_tty_printf("  error : %s not found\n", argv[1] );
    303     }
    304 }
    305 
    306 ///////////////////////////////////////////
    307 static void cmd_kill(int argc, char **argv)
    308 {
    309     if (argc < 2)
    310     {
    311         giet_tty_printf("  usage : %s vspace_name\n", argv[0]);
    312         return;
    313     }
    314 
    315     int ret = giet_kill_application(argv[1]);
    316     if ( ret == -1 )
    317     {
    318         giet_tty_printf("  error : %s not found\n", argv[1] );
    319     }
    320     if ( ret == -2 )
    321     {
    322         giet_tty_printf("  error : %s cannot be killed\n", argv[1] );
    323     }
    324 }
    325 
    326 /////////////////////////////////////////
    327 static void cmd_ps(int argc, char** argv)
    328 {
    329     if (argc == 1)
    330     {
    331         giet_applications_status( NULL );
    332     }
    333     else
    334     {
    335         giet_applications_status( argv[1] );
    336     }
    337 }
    338 
    339 ////////////////////////////////////////////
    340 static void cmd_pause(int argc, char** argv)
    341 {
    342     if (argc < 3)
    343     {
    344         giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
    345         return;
    346     }
    347 
    348     giet_pthread_control( THREAD_CMD_PAUSE , argv[1] , argv[2] );
    349 }
    350 
    351 /////////////////////////////////////////////
    352 static void cmd_resume(int argc, char** argv)
    353 {
    354     if (argc < 3)
    355     {
    356         giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
    357         return;
    358     }
    359 
    360     giet_pthread_control( THREAD_CMD_RESUME , argv[1] , argv[2] );
    361 }
    362 
    363 /////////////////////////////////////////////
    364 static void cmd_context(int argc, char** argv)
    365 {
    366     if (argc < 3)
    367     {
    368         giet_tty_printf("  usage : %s vspace_name thread_name\n", argv[0] );
    369         return;
    370     }
    371 
    372     giet_pthread_control( THREAD_CMD_CONTEXT , argv[1] , argv[2] );
    373 }
    374 
    375 /////////////////////////////////////////////
    376 static void cmd_cat(int argc, char** argv)
    377 {
    378     if (argc != 2)
    379     {
    380         giet_tty_printf("  usage : cat pathname \n");
    381         return;
    382     }
    383 
    384     unsigned int     x,y,p;          // processor coordinates
    385     unsigned int     fd;             // file descriptor
    386     fat_file_info_t  info;           // file info
    387     unsigned int     size;           // buffer size (file_size + 1)
    388     unsigned int     bytes;          // number of bytes to be mapped 
    389     char*            buf = NULL;     // temporary buffer
    390 
    391     // get processor coordinates
    392     giet_proc_xyp( &x , &y , &p );
    393    
    394     // open the file to display   
    395     fd = giet_fat_open( argv[1] , 0 );
    396     if (fd < 0)
    397     {
    398         giet_tty_printf("  error : cannot open %s\n", argv[1]);
    399         goto exit;
    400     }
    401 
    402     // get file size
    403     giet_fat_file_info( fd, &info );
    404     if ( info.is_dir )
    405     {
    406         giet_tty_printf("  error : %s is a directory\n", argv[1] );
    407         goto exit;
    408     }
    409     size = info.size; 
    410 
    411     // extend size to 4 Kbytes boundary if required
    412     if ( (size+1) & 0xFFF)  bytes = (size & 0xFFFFF000) + 0x1000;
    413     else                    bytes = size + 1;
    414 
    415     // map local buffer to Cache_file
    416     buf = giet_fat_mmap( NULL,
    417                          bytes,
    418                          MAP_PROT_READ | MAP_PROT_WRITE,
    419                          MAP_SHARED,
    420                          fd,
    421                          0 );
    422     if ( buf == NULL )
    423     {
    424         giet_tty_printf("  error : cannot map %s\n", argv[1] );
    425         goto exit;
    426     }
    427 
    428     // set terminating '0'
    429     buf[size] = 0;
    430 
    431     // display the file content
    432     giet_tty_printf("%s", buf );
    433 
    434 exit:
    435     if ( fd >= 0 )     giet_fat_close( fd );
    436     if ( buf != NULL ) giet_fat_munmap( buf , bytes );
    437 }
    438 
    439 ///////////////////////////////////////////
    440 static void cmd_dump(int argc, char** argv)
    441 {
    442     if ((argc == 2) && (strcmp( argv[1] , "-bs" ) == 0))
    443     {
    444         giet_fat_dump( DUMP_BS , NULL , 0 );
    445     }
    446     else if ((argc == 2) && (strcmp( argv[1] , "-fs" ) == 0))
    447     {
    448         giet_fat_dump( DUMP_FS , NULL , 0 );
    449     }
    450     else if ((argc == 3) && (strcmp( argv[1] , "-fat" ) == 0))
    451     {
    452         giet_fat_dump( DUMP_FAT , NULL , atoi( argv[2] ) );
    453     }
    454     else if ((argc == 4) && (strcmp( argv[1] , "-file" ) == 0))
    455     {
    456         giet_fat_dump( DUMP_FILE , argv[2] , atoi( argv[3] ) );
    457     }
    458     else if ((argc == 4) && (strcmp( argv[1] , "-dir" ) == 0))
    459     {
    460         giet_fat_dump( DUMP_DIR , argv[2] , atoi( argv[3] ) );
    461     }
    462     else
    463     {
    464         giet_tty_printf("  usage : dump [-bs] [-fs] [-fat block] "
    465                         "[-file pathname block] [-dir pathname block]\n");
    466         return;
    467     }
    468 }
    469 
    470 
    471 ////////////////////////////////////////////////////////////////////
     490
     491/////////////////////////////////////////////////////////////////////////////////////
    472492struct command_t cmd[] =
    473493{
     
    479499    { "help",       "list available commands",              cmd_help },
    480500    { "kill",       "kill an application (all threads)",    cmd_kill },
    481     { "ls",         "list content of a directory",          cmd_ls },
     501    { "log",        "list registered commands",             cmd_log },
     502    { "ls",         "list directory entries",               cmd_ls },
    482503    { "mkdir",      "create a new directory",               cmd_mkdir },
    483504    { "mv",         "move a file in file system",           cmd_mv },
     
    490511    { NULL,         NULL,                                   NULL }
    491512};
    492 
    493 // shell
     513/////////////////////////////////////////////////////////////////////////////////////
     514
     515
     516
    494517
    495518///////////////////////////////////////////////////////////////////
     
    538561        if (!found)
    539562        {
    540             giet_tty_printf("undefined command %s\n", argv[0]);
     563            giet_tty_printf("\n  undefined command %s\n", argv[0]);
    541564        }
    542565    }
    543 }
    544 
    545 ////////////////////
    546 static void prompt()
    547 {
    548     giet_tty_printf("# ");
    549 }
     566} // end parse()
    550567
    551568//////////////////////////////////////////
     
    553570//////////////////////////////////////////
    554571{
    555     char c;
    556     char buf[BUF_SIZE];
    557     int count = 0;
     572    char         c;                              // read character
     573    char         buf[MAX_SIZE];                  // buffer for one command
     574    unsigned int count = 0;                      // pointer in buf
     575    unsigned int i , j;                          // indexes for loops
     576
     577    enum fsm_states
     578    {
     579        NORMAL,
     580        ESCAPE,
     581        BRAKET,
     582    };
    558583
    559584    // get a private TTY
    560585    giet_tty_alloc( 0 );
    561586    giet_tty_printf( "~~~ shell ~~~\n\n" );
     587
     588    // log_buf initialisation
     589    ptw = 0;
     590    ptr = 0;
     591    for ( i = 0 ; i < LOG_DEPTH ; i++ )
     592    {
     593        for ( j = 0 ; j < MAX_SIZE ; j++ )
     594        {
     595            log_buf[i][j] = 0;
     596        }
     597    }
    562598
    563599    // heap initialisation
     
    568604    heap_init( x_id , y_id );
    569605
     606    // command buffer initialisation
     607    for ( i = 0 ; i < sizeof(buf) ; i++ ) buf[i] = 0x20;
     608    count = 0;
     609
    570610    // display first prompt
    571     prompt();
     611    giet_tty_printf("# ");
     612
     613    // This lexical analyser writes one command line in the buf buffer.
     614    // It is implemented as a 3 states FSM to handle the following sequences:
     615    // - ESC [ A : up arrow
     616    // - ESC [ B : down arrow
     617    // - ESC [ C : right arrow
     618    // - ESC [ D : left arrow
     619    // The thee states have the following semantic:
     620    // - NORMAL : no (ESC) character has been found
     621    // - ESCAPE : the character (ESC) has been found
     622    // - BRAKET : the wo characters (ESC,[) have been found
     623    unsigned int state = NORMAL;
    572624
    573625    while (1)
     
    575627        giet_tty_getc(&c);
    576628
    577         switch (c)
    578         {
    579         case '\b':                       // backspace
    580             if (count > 0)
     629        switch ( state )
     630        {
     631            case NORMAL:
     632            { 
     633                if ( c == '\b' )          // backspace => remove one character from buffer
     634                {
     635                    if (count > 0)
     636                    {
     637                        giet_tty_printf("\b \b");
     638                        count--;
     639                    }
     640                }
     641                else if ( c == '\n' )     // new line => call parser to execute command
     642                {
     643                    if (count > 0)
     644                    {
     645                        // complete commande
     646                        buf[count] = '\0';
     647
     648                        // register command in log arrays       
     649                        strcpy( &log_buf[ptw][0] , buf );
     650                        log_count[ptw] = count;
     651                        ptw = (ptw + 1) % LOG_DEPTH;
     652                        ptr = ptw;
     653
     654                        // execute command
     655                        giet_tty_printf("\n");
     656                        parse((char*)&buf);
     657
     658                        // reinitialise buffer and display prompt
     659                        for ( i = 0 ; i < sizeof(buf) ; i++ ) buf[i] = 0x20;
     660                        count = 0;
     661                        giet_tty_printf("# ");
     662                    }
     663                }
     664                else if ( c == '\t' )    // tabulation => do nothing
     665                {
     666                }
     667                else if ( c == 0x1B )    // ESC => start an escape sequence
     668                {
     669                    state = ESCAPE;
     670                }
     671                else if ( c == 0x03 )    // ^C  => cancel current command
     672                {
     673                    for ( i = 0 ; i < count ; i++ ) giet_tty_printf("\b \b");
     674                    for ( i = 0 ; i < sizeof(buf) ; i++ ) buf[i] = 0x20;
     675                    count = 0;
     676                }
     677                else                     // register character in command buffer
     678                {
     679                    if (count < sizeof(buf) - 1)
     680                    {
     681                        giet_tty_printf("%c", c);
     682                        buf[count] = c;
     683                        count++;
     684                    }
     685                }
     686                break;
     687            }
     688            case ESCAPE:
    581689            {
    582                 giet_tty_printf("\b \b");
    583                 count--;
     690                if ( c == '[' )        //  valid sequence => continue
     691                {
     692                    state = BRAKET;
     693                }
     694                else                   // invalid sequence => do nothing
     695                {
     696                    state = NORMAL;
     697                }
     698                break;
    584699            }
    585             break;
    586         case '\n':                       // new line
    587             giet_tty_printf("\n");
    588             if (count > 0)
     700            case BRAKET:
    589701            {
    590                 buf[count] = '\0';
    591                 parse((char*)&buf);
     702                if      ( c == 'D' )   // valid  LEFT sequence => move buf pointer left
     703                {
     704                    if ( count > 0 )
     705                    {
     706                        giet_tty_printf("\b");
     707                        count--;
     708                    }
     709
     710                    // get next user char
     711                    state = NORMAL;
     712                }
     713                else if ( c == 'C' )   // valid  RIGHT sequence => move buf pointer right
     714                {
     715                    if ( count < sizeof(buf) - 1)
     716                    {
     717                        giet_tty_printf("%c", buf[count] );
     718                        count++;
     719                    }
     720
     721                    // get next user char
     722                    state = NORMAL;
     723                }
     724                else if ( c == 'A' )   // valid  UP sequence => move log pointer backward
     725                {
     726                    // cancel current command
     727                    for ( i = 0 ; i < count ; i++ ) giet_tty_printf("\b \b");
     728                    count = 0;
     729
     730                    // copy log command into buf
     731                    ptr = (ptr - 1) % LOG_DEPTH;
     732                    strcpy( buf , &log_buf[ptr][0] );
     733                    count = log_count[ptr];
     734
     735                    // display log command
     736                    giet_tty_printf( "%s" , buf );
     737
     738                    // get next user char
     739                    state = NORMAL;
     740                }
     741                else if ( c == 'B' )   // valid  DOWN sequence => move log pointer forward
     742                {
     743                    // cancel current command
     744                    for ( i = 0 ; i < count ; i++ ) giet_tty_printf("\b \b");
     745                    count = 0;
     746
     747                    // copy log command into buf
     748                    ptr = (ptr + 1) % LOG_DEPTH;
     749                    strcpy( buf , &log_buf[ptr][0] );
     750                    count = log_count[ptr];
     751
     752                    // display log command
     753                    giet_tty_printf( "%s" , buf );
     754
     755                    // get next user char
     756                    state = NORMAL;
     757                }
     758                else                   // other character => do nothing
     759                {
     760                    // get next user char
     761                    state = NORMAL;
     762                }
     763                break;
    592764            }
    593             prompt();
    594             count = 0;
    595             break;
    596         case '\t':                       // tabulation
    597             // do nothing
    598             break;
    599         case '\03':                      // ^C
    600             giet_tty_printf("^C\n");
    601             prompt();
    602             count = 0;
    603             break;
    604         default:                         // regular character
    605             if (count < sizeof(buf) - 1)
    606             {
    607                 giet_tty_printf("%c", c);
    608                 buf[count] = c;
    609                 count++;
    610             }
    611         }
    612     }
    613 } // end main()
     765        }  // end switch on state 
     766    }  // end while
     767}  // end main()
    614768
    615769// Local Variables:
Note: See TracChangeset for help on using the changeset viewer.