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

📄 shell.c

📁 MIPS YAMON, a famous monitor inc. source, make file and PDF manuals.
💻 C
📖 第 1 页 / 共 5 页
字号:
 *                          add2buf ************************************************************************/static voidadd2buf(     t_shell_line_buf *buf,    char	     *line ){    UINT32 current_from_buf;    char   previous_line[SHELL_MAX_COMMAND_LEN + 1];    UINT32 len, i;    current_from_buf = buf->free;    /* Check for identical command on stack */    if( get_previous( buf, &current_from_buf, previous_line ) &&        strcmp( line, previous_line ) == 0 )    {        return;    }    /* Copy line to buffer */    for( i=0, len = strlen(line); i<=len; i++ )    {        /* Before inserting character, we check if we are about         * to overwrite an old line.         */        if( buf->free == buf->first )        {            /* We are about to overwrite an old line,	     * so obsolete the old line	     */            while(buf->data[buf->first] != '\0')            {                INCWRAP(buf->first, BUFFERSIZE);            }            INCWRAP(buf->first, BUFFERSIZE);        }        /* Now we are ready to insert the character */        buf->data[buf->free] = line[i];        INCWRAP(buf->free, BUFFERSIZE);        /* After moving the free pointer forward, we need to check	 * again if 'free' has caught up with 'first'.	 */        if( buf->free == buf->first )        {            /* free did catch up with first, so obsolete the old line. */            while(buf->data[buf->first] != '\0')            {                INCWRAP(buf->first, BUFFERSIZE);            }            INCWRAP(buf->first, BUFFERSIZE);        }    }    /* Buffer is no longer unused */    if( buf->first == BUFFER_NU )         buf->first = 0;}/************************************************************************ *                          command_loop ************************************************************************/static voidcommand_loop(    t_shell_line_buf *buf ){    char   line[SHELL_MAX_COMMAND_LEN + 1];    UINT32 current_from_buf;    bool   execute;    while( TRUE )    {        print_prompt( PROMPT_TARGET_DISPLAY, PROMPT_TEXT_ENV );	if( !start )            print_prompt( PROMPT_TARGET_TERMINAL, PROMPT_TEXT_ENV );        if( !shell_get_line( line, SHELL_MAX_COMMAND_LEN, TRUE, TRUE, buf ) )	{	    printf( "\n" );	}	else	{	    /* Remove excess spaces */	    remove_space( line );	    if( strlen(line) == 0 )	        printf( "\n" );	    else	    {	        execute = TRUE;	        if( strcmp( line, "." ) == 0 )		{		    shell_dot = TRUE;		    current_from_buf = buf->free;		    if(!get_previous( buf, &current_from_buf, line ))		    {		        execute = FALSE;		        printf( "\n" );		    }		}		else		{		    shell_dot = FALSE;	            /* Add line to stack (only "single" lines) */		    if( !start && (strlen( line ) <= max_line_len) )	                add2buf( buf, line );		}		if( execute )		{    		    /*  Recursively split line in ";" separated		     *  commands and expand environment variables.		     *  Execute command(s).		     */		    newline_after_prompt = FALSE;		    execute_line( line, TRUE );		}            }        }	start = NULL;    }}/************************************************************************ *                          remove_space ************************************************************************/static voidremove_space(     char *line ){    char   clean[SHELL_MAX_COMMAND_LEN + 1];    UINT32 len = 0;    bool   skip;    bool   found_char   = FALSE;    char   *start       = line;    bool   quote_double = FALSE;    bool   quote_single = FALSE;    bool   special	= FALSE;    while( line[0] != '\0' )    {        skip = FALSE;        /*  Remove excess whitespace, unless within single or	 *  double quotes.	 */        if( line[0] == ' ' )	{	    if( !found_char        ||  /* Leading spaces  */	        (line[1] == ' ')   ||  /* Multiple spaces */		(line[1] == '\0') )    /* Trailing spaces */            {	        /* Keep spaces within quotes */	        if( !quote_double && !quote_single )		{	            skip = TRUE;		}	    }        }	else if( line[0] == '\\' )	{	    special = !special;	}	else if( (line[0] == '\'') && !special )	{	    if( !quote_double )	    {	        quote_single = !quote_single;	    }	}	else if( (line[0] == '"') && !special )	{	    if( !quote_single )	    {	        quote_double = !quote_double;	    }	}	else	    special = FALSE;	if( !skip )	{	    clean[len++] = line[0];	    found_char   = TRUE;        }	line++;    }    clean[len] = '\0';    strcpy( start, clean );}/************************************************************************ *                          separate ************************************************************************/static voidseparate(    char   *line,    UINT32 *subcommand_count ){    bool   quote_double = FALSE;    bool   quote_single = FALSE;    bool   special	= FALSE;    *subcommand_count = 1;    /*  Find ';' not within single or double quotes and substitute     *  with '\0'     */    while( line[0] != '\0' )    {        if( (*line == ';') && !quote_double && !quote_single )	{            *line = '\0';	    (*subcommand_count)++;        }	else if( *line == '\\' )	{	    special = !special;	}	else if( (*line == '\'') && !special )	{	    if( !quote_double )	    {	        quote_single = !quote_single;	    }	}	else if( (*line == '"') && !special )	{	    if( !quote_single )	    {	        quote_double = !quote_double;	    }	}	else	    special = FALSE;	line++;    }}/************************************************************************ *                          get_repeat ************************************************************************/static boolget_repeat(    char   *line,    UINT32 *loop_count ){    t_shell_option decode;    UINT32	   len;    if( *line == '+' )    {        line++;	/* Remove trailing spaces */	len = strlen( line );		while( len && line[len-1] == ' ' )	{	    line[len-1] = '\0';	    len--;	}	/* Decode number */        if( shell_decode_number(	            &decode, 		    NULL,	            line ) )	{	    *loop_count = decode.number;	    return TRUE;	}    }    return FALSE;}/************************************************************************ *                          expand_line ************************************************************************/static UINT32expand_line(     char *line ){    char            env_name[SHELL_MAX_ENV_LEN + 2];    char            expanded[SHELL_MAX_COMMAND_LEN + 1];    UINT32          len, env_len;    t_expand_state  state;    char	    *ch;    UINT32	    rc;		      state   = STATE_EXP_NORMAL;    ch      = line;    len	    = 0;    env_len = 0;    rc	    = OK;    do    {        switch( state )	{	  case STATE_EXP_NORMAL :	    switch( *ch )	    {	      case '\0' :	        expanded[len++] = *ch;	        state = STATE_EXP_DONE;		break;	      case '$'  :	        env_len = 0;	        state = STATE_EXP_ENV;		break;	      case '\\' :	        expanded[len++] = *ch;	        state = STATE_EXP_SPECIAL;		break;	      case '\'' :	        expanded[len++] = *ch;	        state = STATE_EXP_QUOTE_SINGLE;		break;	      case '"' :	        expanded[len++] = *ch;	        state = STATE_EXP_QUOTE_DOUBLE;		break;	      case ' '  :	      default   :	        expanded[len++] = *ch;		state = STATE_EXP_NORMAL;		break;	    }	    break;	  case STATE_EXP_ENV :	    switch( *ch )	    {	      case '\0' :		rc = add_env( env_name, env_len, expanded, &len );		expanded[len++] = *ch;		state = STATE_EXP_DONE;		break;	      case '$'  :		rc = add_env( env_name, env_len, expanded, &len );		env_len = 0;		state = STATE_EXP_ENV;		break;	      case '\\' :		rc = add_env( env_name, env_len, expanded, &len );		expanded[len++] = *ch;		state = STATE_EXP_SPECIAL;		break;	      case '\'' :		rc = add_env( env_name, env_len, expanded, &len );		expanded[len++] = *ch;				state = STATE_EXP_QUOTE_SINGLE;		break;	      case '"' :		rc = add_env( env_name, env_len, expanded, &len );		expanded[len++] = *ch;				state = STATE_EXP_QUOTE_DOUBLE;		break;	      case ' ' :		rc = add_env( env_name, env_len, expanded, &len );		expanded[len++] = *ch;				state = STATE_EXP_NORMAL;		break;	      default   :	        env_name[env_len++] = *ch;		state = STATE_EXP_ENV;		break;	    }	    break;	  case STATE_EXP_SPECIAL :	    switch( *ch )	    {	      case '\0' :	        expanded[len++] = *ch;	        state = STATE_EXP_DONE;		break;	      case '$'  :	      case '\\' :	      case '\'' :	      case '"'  :	      case ' '  :	      default   :	        expanded[len++] = *ch;		state = STATE_EXP_NORMAL;		break;	    }	    break;	  case STATE_EXP_QUOTE_SINGLE :	    switch( *ch )	    {	      case '\0' :	        rc = SHELL_ERROR_PARSE_MISSING_QUOTE;		break;	      case '\\' :	        expanded[len++] = *ch;	        state = STATE_EXP_QUOTE_SINGLE_SPECIAL;		break;	      case '\'' :	        expanded[len++] = *ch;	        state = STATE_EXP_NORMAL;		break;	      case '"' : 	      case '$' :	      case ' ' :	      default  :	        expanded[len++] = *ch;		state = STATE_EXP_QUOTE_SINGLE;		break;	    }	    break;	  case STATE_EXP_QUOTE_DOUBLE :	    switch( *ch )	    {	      case '\0' :	        rc = SHELL_ERROR_PARSE_MISSING_QUOTE;		break;	      case '$'  :	        env_len = 0;	        state = STATE_EXP_QUOTE_DOUBLE_ENV;		break;	      case '\\' :	        expanded[len++] = *ch;	        state = STATE_EXP_QUOTE_DOUBLE_SPECIAL;		break;	      case '"' :	        expanded[len++] = *ch;	        state = STATE_EXP_NORMAL;		break;	      case '\'' :	      case ' '  :	      default   :	        expanded[len++] = *ch;		state = STATE_EXP_QUOTE_DOUBLE;		break;	    }	    break;	  case STATE_EXP_QUOTE_SINGLE_SPECIAL :	    switch( *ch )	    {	      case '\0' :	        rc = SHELL_ERROR_PARSE_MISSING_QUOTE;		break;	      case '$' :	      case '\\':	      case '\'':	      case '"' :	      case ' ' :	      default  :	        expanded[len++] = *ch;		state = STATE_EXP_QUOTE_SINGLE;		break;	    }	    break;	  case STATE_EXP_QUOTE_DOUBLE_SPECIAL :	    switch( *ch )	    {	      case '\0' :	        rc = SHELL_ERROR_PARSE_MISSING_QUOTE;		break;	      case '$' :	      case '\\':	      case '\'':	      case '"' :	      case ' ' :	      default  :	        expanded[len++] = *ch;		state = STATE_EXP_QUOTE_DOUBLE;		break;	    }	    break;	  case STATE_EXP_QUOTE_DOUBLE_ENV :	    switch( *ch )	    {	      case '\0' :		rc = SHELL_ERROR_PARSE_MISSING_QUOTE;		break;	      case '$'  :		rc = add_env( env_name, env_len, expanded, &len );		env_len = 0;		state = STATE_EXP_QUOTE_DOUBLE_ENV;		break;	      case '\\' :		rc = add_env( env_name, env_len, expanded, &len );		expanded[len++] = *ch;		state = STATE_EXP_QUOTE_DOUBLE_SPECIAL;		break;	      case '"' :		rc = add_env( env_name, env_len, expanded, &len );		expanded[len++] = *ch;				state = STATE_EXP_NORMAL;		break;	      case '\'' :	      case ' '  :	      case ';'  :		rc = add_env( env_name, env_len, expanded, &len );		expanded[len++] = *ch;				state = STATE_EXP_QUOTE_DOUBLE;		break;	      default   :	        env_name[env_len++] = *ch;		state = STATE_EXP_QUOTE_DOUBLE_ENV;		break;	    }	    break;	  default : /* Should not happen */	    rc = SHELL_ERROR_STRUCTURE;	    break;	}	if( (len == SHELL_MAX_COMMAND_LEN + 1) && (state != STATE_EXP_DONE) )	    rc = SHELL_ERROR_PARSE_LONG_LINE;	if( env_len == SHELL_MAX_ENV_LEN + 1 )	    rc = SHELL_ERROR_PARSE_LONG_ENV;	ch++;    }    while( (rc == OK) && (state != STATE_EXP_DONE) );        if( rc != OK )        return rc;    else    {

⌨️ 快捷键说明

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