⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shell.c

📁 MIPS下的boottloader yamon 的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			  cmd = cmd_list[i];
			  
			  if( strstr( cmd->name, name ) == cmd->name )
			  {
				  /* Found match */
				  
				  if( strcmp( cmd->name, name ) == 0 )
				  {
					  /* Exact match */
					  if(len)
						  *len = strlen( cmd->name );
					  
					  cmd_found = cmd;
					  break;
				  }
				  
				  if( cmd_found )
				  {
					  /* Got one already */
					  UINT32 t;
					  
					  /* Determine the common characters */
					  for( t=0; cmd_found->name[t] == cmd->name[t]; t++ );
					  
					  if(len)
						  *len = MIN(t, *len);
					  
					  if(ambivalent)
						  *ambivalent = TRUE;
				  }
				  else
				  {
					  if( strlen(name) > 1 ) /* Min 2 char for autocompletion */
					  {
						  cmd_found = cmd;
						  
						  if(len)
							  *len = strlen(cmd->name);
					  }
				  }
			  } 
		  }
		  
		  /* Hack in order to handle case insensitivity of 
		  * Microsoft SDB commands.
		  */
		  if( strlen( name ) == 1 )
		  {
			  *name = ch;
		  }
		  
		  return cmd_found;
	  }
	  
	  
	  /************************************************************************
	  *
	  *                          shell_print_dot
	  *  Description :
	  *  -------------
	  *
	  *  Print dot on screen
	  *
	  *  Return values :
	  *  ---------------
	  *
	  *  void
	  *
	  ************************************************************************/
	  bool
		  shell_print_dot(
		  UINT32 *count )
	  {
		  return SHELL_PUTS( ( (++(*count) % 40) == 0 ) ? ".\n" : "." );
	  }
	  
	  
	  /************************************************************************
	  *
	  *                          shell_setmore
	  *  Description :
	  *  -------------
	  *
	  *  Enable/disable 'more' control from shell_puts and shell_putc
	  *
	  *  Return values :
	  *  ---------------
	  *
	  *  None
	  *
	  ************************************************************************/
	  void
		  shell_setmore(
		  bool enable_more )
	  {
		  more        = enable_more;
		  linenum     = 0;
		  indent_prev = 0;
	  }
	  
	  
	  /************************************************************************
	  *
	  *                          shell_puts
	  *  Description :
	  *  -------------
	  *
	  *  Print string to stdout
	  *
	  *  Return values :
	  *  ---------------
	  *
	  *  TRUE -> Ctrl^C was pressed
	  *
	  ************************************************************************/
	  bool
		  shell_puts(
		  char   *string,
		  UINT32 indent )
	  {
		  UINT32 count, len;
		  UINT32 first_newline;
		  bool   nl;
		  char   ch;
		  bool   rc;
		  
		  UINT32 linemax, linewidth;
		  
#if 0
		  linemax   = getenv( "linemax" );
		  linewidth = getenv( "linewidth" );
#else
		  linemax   = MON_DEF_LINEMAX - 1; /* Space for 'Press Ctrl-c ... message */
		  linewidth = MON_DEF_LINEWIDTH;
#endif
		  
		  if( linewidth <= indent )		/* This is an error		*/
			  return TRUE;
		  
		  while( *string != '\0' )
		  {
			  if( linenum == linemax )
			  {
				  /* Print 'press any key...' message */
				  PUTS( DEFAULT_PORT, continue_msg );
				  
				  while( !GETCHAR( DEFAULT_PORT, &ch ) );
				  
				  /* Remove 'press any key...' message */
				  len = strlen( continue_msg );
				  moveleft( len );
				  for(count=0; count<len; count++)
				  {
					  PUTCHAR( DEFAULT_PORT, ' ' );
				  }
				  moveleft( len );
				  
				  if( ch == CTRL_C )
				  {
					  linenum     = 1; /* Keep last line */
					  ctrl_c_flag = TRUE;
					  return TRUE;
				  }
				  else
				  {
					  linenum = 
						  ( (ch == CR) || (ch == LF) ) ?
						  linemax - 1 :
					  1;   /* Keep last line */
					  indent_prev = 0;
				  }
			  }
			  
			  /* Indent */
			  if( indent )
			  {
				  if (indent < indent_prev)
					  indent = indent_prev;
				  count        = indent - indent_prev;
				  indent_prev += count;
			  }
			  else	  
				  count = 0;
			  
			  while(count--)
			  {
				  PUTCHAR( DEFAULT_PORT, ' ' );
			  }
			  
			  first_newline = strcspn( string, "\n" );
			  
			  count = ( first_newline + indent <= linewidth ) ?
				  first_newline + 1 : 
			  linewidth - indent;
			  
			  while( count-- && (*string != '\0') )
			  {
				  nl = (*string == '\n');
				  PUTCHAR( DEFAULT_PORT, *(string++) );
				  indent_prev++;
				  
				  if(nl) 
				  {
					  indent_prev = 0;
					  if( more ) 
						  linenum++;
				  }
			  }
			  
			  if( (*string != '\0') && (!nl) )
			  {
				  PUTCHAR( DEFAULT_PORT, '\n' );
				  indent_prev = 0;
				  if( more )
					  linenum++;
			  }
		  }
		  
		  rc = GETCHAR_CTRLC( DEFAULT_PORT );
		  
		  if( rc )
			  ctrl_c_flag = TRUE;
		  
		  return rc;
}


/************************************************************************
*
*                          shell_putc
*  Description :
*  -------------
*
*  Print char to stdout
*
*  Return values :
*  ---------------
*
*  TRUE -> Ctrl^C was pressed
*
************************************************************************/
bool
shell_putc(
		   char   ch,
		   UINT32 indent )
{
    char s[2];
    
    s[0] = ch;
    s[1] = '\0';
	
    return shell_puts( s, indent );
}


/************************************************************************
*
*                          shell_get_line
*  Description :
*  -------------
*
*  Get command line with handling of special characters
*
*  Return values :
*  ---------------
*
*  FALSE -> Ctrl^C was pressed
*
************************************************************************/
bool
shell_get_line(
			   char       *line,	    /* Line buffer                                       */
			   UINT32     maxchars,    /* Max number of chars not counting terminating '\0' */
			   bool       first_line,  /* TRUE -> First line (ie not a \CR continuation)	 */
			   bool       full,	    /* TRUE -> Handle command stack and autocompletion   */
			   t_shell_line_buf *buf ) /* Command stack (only used if full == TRUE)	 */
{
    UINT32  cursor, eol;
    char    ch;
    UINT32  slash_count;
    bool    line_shift, line_done;
    UINT32  len;
    t_cmd   *cmd;
    UINT32  current_from_buf;
	
    if( start )
    {
        /* Use $start as the first command line */
        strcpy( line, "$start" );
		return TRUE;
    }
	
    *line            = '\0';
    cursor	     = 0;
    eol		     = 0;
    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, &current_from_buf, line ) )
            {
				/* Delete line */
				delete_line( &cursor, &eol );
				
				/* Update settings and print line */
				cursor = eol = strlen( line );
				printf( line );
            }
			
            break;      
			
		case CTRL_N :
			/* Next command in command stack (first line only) */
			
			if( full && first_line && 
				get_next( buf, &current_from_buf, line ) )
			{
				/* Delete line */
				delete_line( &cursor, &eol );
				
				/* Update settings and print line */
				cursor = eol = strlen( line );
				printf( 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( 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 void
print_prompt(
			 UINT32 target,
			 UINT32 text )
{
    char *s;
	
    if( text == PROMPT_TEXT_ENV )
    {
        if( !env_get( "prompt", &s, NULL, 0 ) )
            s = DEFAULT_PROMPT;
    }
    else
    {
        s = "\n?";
    }
	
    if( target == PROMPT_TARGET_DISPLAY )
    {
        DISP_STR( s );
    }
    else
    {
        printf( s );
        printf( (text == PROMPT_TEXT_ENV) ? "> " : " " );
		
		max_line_len = SHELL_MAX_LINE_LEN - strlen(s) - 2;
    }
}


/************************************************************************
*                          receive
************************************************************************/
static void
receive( 
		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 void
moveleft(
		 UINT32 count )
{
    while( count-- )
    {
        PUTCHAR( DEFAULT_PORT, '\b' );
    }       
}


/************************************************************************
*                          moveright
************************************************************************/
static void
moveright(
		  char    *line,
		  UINT32  cursor,
		  UINT32  count )
{
    while( count-- )
    {
        PUTCHAR( DEFAULT_PORT, line[cursor++] );
    }
}


/************************************************************************
*                          get_previous
************************************************************************/
static bool
get_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;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -