📄 shell.c
字号:
line_done = FALSE; line_shift = FALSE; if( full && !buf ) /* Should not happen */ return FALSE; if( full ) current_from_buf = buf->free; while( !line_done && !line_shift ) { receive( &ch ); switch( ch ) { case CR : case LF : /* End line unless last characters were an * odd number of '\' chars, in which * case input continues on new line. */ for( slash_count = 0; (eol - slash_count > 0) && (line[eol - slash_count - 1] == '\\'); slash_count++ ) { ; } if( (slash_count % 2) == 1 ) line_shift = TRUE; else line_done = TRUE; break; case CTRL_C : /* Cancel line */ return FALSE; case CTRL_A : /* Move cursor to the far left */ moveleft( cursor ); cursor = 0; break; case CTRL_E : /* Move cursor to the far right */ moveright( line, cursor, eol - cursor ); cursor = eol; break; case CTRL_B : /* ^B or left arrow : Move cursor left */ if( cursor > 0 ) { moveleft(1); cursor--; } break; case CTRL_F : /* ^F or right arrow : Move cursor right */ if( cursor < eol ) { moveright(line, cursor, 1); cursor++; } break; case CTRL_D : /* Delete character after cursor */ if( cursor < eol ) { delete_char( line, &cursor, &eol ); } break; case CTRL_H : /* Same as DEL */ case DEL : /* Delete character at cursor */ if( cursor > 0 ) { moveleft(1); cursor--; delete_char(line, &cursor, &eol ); } break; case CTRL_K : /* Delete everything after cursor */ delete_from_cursor(cursor, &eol); line[eol] = '\0'; break; case CTRL_U : /* Delete line */ delete_line( &cursor, &eol ); line[eol] = '\0'; break; case CTRL_P : /* Previous command in command stack (first line only) */ if( full && first_line && get_previous( buf, ¤t_from_buf, line ) ) { /* Delete line */ delete_line( &cursor, &eol ); /* Update settings and print line */ cursor = eol = strlen( line ); printf( "%s",line ); } break; case CTRL_N : /* Next command in command stack (first line only) */ if( full && first_line && get_next( buf, ¤t_from_buf, line ) ) { /* Delete line */ delete_line( &cursor, &eol ); /* Update settings and print line */ cursor = eol = strlen( line ); printf( "%s",line ); } break; case TAB : /* Command line completion (first line only) */ if( full && first_line ) { cmd = shell_lookup_cmd( line, NULL, &len, command_list, command_count ); if( cmd ) { /* Delete old line */ delete_line( &cursor, &eol ); /* Insert new line */ strncpy( line, cmd->name, len ); line[len] = '\0'; cursor = len; eol = len; /* Print line */ printf( "%s",line ); } } break; default : if( isprint(ch) && (eol < MIN(maxchars, max_line_len )) ) insert_char( line, &cursor, &eol, ch ); break; } } if( line_shift ) { print_prompt( PROMPT_TARGET_TERMINAL, PROMPT_TEXT_CONT ); eol--; /* Remove '\' */ return shell_get_line( &line[eol], maxchars - eol, FALSE, full, buf ); } return TRUE;}/************************************************************************ * Implementation : Static functions ************************************************************************//************************************************************************ * print_prompt ************************************************************************/static voidprint_prompt( UINT32 target, UINT32 text ){ char *s; bool b; if( text == PROMPT_TEXT_ENV ) { if( !env_get( "prompt", &s, NULL, 0 ) ) s = sys_default_prompt; } else { s = "\n?"; } if( target == PROMPT_TARGET_DISPLAY ) { /* Freeze display for the first prompt after shell is reentered */ if (display_freeze) { display_freeze = FALSE; /* Acknowledge NMI (doesn't harm if nmi is not active) */ SYSCON_write(SYSCON_BOARD_NMI_ACK_ID, &b, sizeof(b)); return; } if (!strcmp(s, sys_default_prompt)) { /* Prompt is default - show default display */ s = sys_default_display; } DISP_STR( s ); } else { printf( "%s",s ); printf( (text == PROMPT_TEXT_ENV) ? "> " : " " ); max_line_len = SHELL_MAX_LINE_LEN - strlen(s) - 2; }}/************************************************************************ * receive ************************************************************************/static voidreceive( char *ch ){ t_rcv_state state = STATE_RCV_START; while( state != STATE_RCV_DONE ) { while( !GETCHAR( DEFAULT_PORT, ch ) ); switch( state ) { case STATE_RCV_START : if ( *ch == ESC ) state = STATE_RCV_ESC; else if( *(unsigned char *)ch == CSI ) state = STATE_RCV_CSI; else state = STATE_RCV_DONE; break; case STATE_RCV_ESC : if( *ch == '[' ) state = STATE_RCV_BRACKET; else state = STATE_RCV_START; break; case STATE_RCV_CSI : case STATE_RCV_BRACKET : state = STATE_RCV_DONE; switch( *ch ) { case 'A': *ch = CTRL_P; break; case 'B': *ch = CTRL_N; break; case 'C': *ch = CTRL_F; break; case 'D': *ch = CTRL_B; break; default : state = STATE_RCV_START; } break; default : break; } }}/************************************************************************ * moveleft ************************************************************************/static voidmoveleft( UINT32 count ){ while( count-- ) { PUTCHAR( DEFAULT_PORT, '\b' ); } }/************************************************************************ * moveright ************************************************************************/static voidmoveright( char *line, UINT32 cursor, UINT32 count ){ while( count-- ) { PUTCHAR( DEFAULT_PORT, line[cursor++] ); }}/************************************************************************ * get_previous ************************************************************************/static boolget_previous( t_shell_line_buf *buf, UINT32 *current_from_buf, char *line ){ if( buf->first == BUFFER_NU ) return FALSE; if( *current_from_buf == buf->first ) return FALSE; /* Move backward */ DECWRAP(*current_from_buf, BUFFERSIZE); do { DECWRAP(*current_from_buf, BUFFERSIZE); } while( (buf->data[*current_from_buf] != '\0') && (*current_from_buf != buf->first) ); if( *current_from_buf != buf->first ) { /* One too far, so move increase by 1 */ INCWRAP(*current_from_buf, BUFFERSIZE); } copybuf( line, buf->data, *current_from_buf, BUFFERSIZE ); return TRUE;}/************************************************************************ * get_next ************************************************************************/static boolget_next( t_shell_line_buf *buf, UINT32 *current_from_buf, char *line ){ if( buf->first == BUFFER_NU ) return FALSE; if( *current_from_buf == buf->free ) return FALSE; /* Move forward */ do { INCWRAP(*current_from_buf, BUFFERSIZE); } while( buf->data[*current_from_buf] != '\0' ); INCWRAP(*current_from_buf, BUFFERSIZE); if( *current_from_buf == buf->free ) { line[0] = '\0'; } else { /* Do the copy */ copybuf( line, buf->data, *current_from_buf, BUFFERSIZE ); } return TRUE;}/************************************************************************ * copy_buf ************************************************************************/static void copybuf( char *dst, char *src, UINT32 pos, UINT32 bufsize ){ do { *dst = src[pos]; INCWRAP(pos, bufsize ); } while( *(dst++) != '\0' );}/************************************************************************ * decode_option ************************************************************************/static booldecode_option( t_shell_option *decode, UINT32 *type, char *token ){ if( *token == '-' ) { decode->option = &token[1]; *type = SHELL_TOKEN_OPTION; return TRUE; } else return FALSE; }/************************************************************************ * decode_ip ************************************************************************/static booldecode_ip( t_shell_option *decode, UINT32 *type, char *token ){ if( env_ip_s2num( token, (void *)&decode->ip, sizeof(decode->ip)) ) { *type = SHELL_TOKEN_IP; return TRUE; } else return FALSE;}/************************************************************************ * insert_char ************************************************************************/static voidinsert_char( char *line, UINT32 *cursor, UINT32 *eol, char ch ){ UINT32 i; /* Move characters after cursor and insert new character */ for( i = *eol; i > *cursor; i-- ) line[i] = line[i-1]; line[i] = ch; /* Increase line length and add new termination */ (*eol)++; line[*eol] = '\0'; /* Print line from cursor */ printf("%s", &line[*cursor] ); /* Increase cursor */ (*cursor)++; /* Move cursor back */ moveleft(*eol - *cursor);}/************************************************************************ * delete_char ************************************************************************/static voiddelete_char( char *line, UINT32 *cursor, UINT32 *eol ){ UINT32 i; /* Move characters after cursor and insert new character */ for( i = *cursor; i < *eol; i++ ) line[i] = line[i+1]; /* Print line from cursor, add space */ printf( "%s ", &line[*cursor] ); /* Move cursor back */ moveleft( *eol - *cursor ); /* Decrease line length */ (*eol)--;}/************************************************************************ * delete_from_cursor ************************************************************************/static voiddelete_from_cursor( UINT32 cursor, UINT32 *eol){ char spaces[SHELL_MAX_LINE_LEN + 1]; UINT32 i; /* Replace characters to the right of cursor with spaces */ for(i=0; i < (*eol - cursor); i++) spaces[i] = ' '; spaces[i] = '\0'; printf( spaces ); /* Move cursor back */ moveleft( *eol - cursor ); /* Move eol to cursor location */ *eol = cursor;}/************************************************************************ * delete_line ************************************************************************/static voiddelete_line( UINT32 *cursor, UINT32 *eol ){ moveleft( *cursor ); *cursor = 0; delete_from_cursor(*cursor, eol );}/************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -