📄 shell.c
字号:
strcpy( line, expanded ); return OK; }}/************************************************************************ * add_env ************************************************************************/static UINT32add_env( char *env_name, UINT32 env_len, char *expanded, UINT32 *len_expanded ){ char *env_val; env_name[env_len] = '\0'; expanded[*len_expanded] = '\0'; /* Lookup env variable */ if( env_get( env_name, &env_val, NULL, 0 ) ) { *len_expanded += strlen(env_val); if( *len_expanded > SHELL_MAX_COMMAND_LEN ) return SHELL_ERROR_PARSE_LONG_LINE; else { strcat( expanded, env_val ); return OK; } } else return SHELL_ERROR_PARSE_UNKNOWN_ENV;}/************************************************************************ * tokenize ************************************************************************/static UINT32tokenize( char *line ){ t_tokenize_state state; char *s; UINT32 len; UINT32 rc; state = STATE_TOKENIZE_SEARCH; argc = 0; len = 0; s = argv[argc]; rc = OK; do { switch( state ) { case STATE_TOKENIZE_SEARCH : switch( *line ) { case '\\' : state = STATE_TOKENIZE_SPECIAL; break; case '\'' : state = STATE_TOKENIZE_QUOTE_SINGLE; break; case '"' : state = STATE_TOKENIZE_QUOTE_DOUBLE; break; case ' ' : state = STATE_TOKENIZE_SEARCH; break; case '\0' : state = STATE_TOKENIZE_DONE; break; default : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else { *s = *line; s++; len++; state = STATE_TOKENIZE_WORD; } break; } break; case STATE_TOKENIZE_SPECIAL : switch( *line ) { case '\0' : state = STATE_TOKENIZE_DONE; break; case '\\' : case '\'' : case '"' : default : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else if( len == SHELL_MAX_TOKEN_LEN ) rc = SHELL_ERROR_PARSE_LONG_TOKEN; else { *s = *line; s++; len++; state = STATE_TOKENIZE_WORD; } break; } break; case STATE_TOKENIZE_QUOTE_DOUBLE : switch( *line ) { case '\\' : state = STATE_TOKENIZE_QUOTE_DOUBLE_SPECIAL; break; case '"' : state = STATE_TOKENIZE_WORD; break; case '\0' : /* Should not happen */ rc = SHELL_ERROR_PARSE_MISSING_QUOTE; break; case ' ' : case '\'' : default : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else if( len == SHELL_MAX_TOKEN_LEN ) rc = SHELL_ERROR_PARSE_LONG_TOKEN; else { *s = *line; s++; len++; state = STATE_TOKENIZE_QUOTE_DOUBLE; } break; } break; case STATE_TOKENIZE_QUOTE_SINGLE : switch( *line ) { case '\\' : state = STATE_TOKENIZE_QUOTE_SINGLE_SPECIAL; break; case '\'' : state = STATE_TOKENIZE_WORD; break; case '\0' : /* Should not happen */ rc = SHELL_ERROR_PARSE_MISSING_QUOTE; break; case ' ' : case '"' : default : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else if( len == SHELL_MAX_TOKEN_LEN ) rc = SHELL_ERROR_PARSE_LONG_TOKEN; else { *s = *line; s++; len++; state = STATE_TOKENIZE_QUOTE_SINGLE; } break; } break; case STATE_TOKENIZE_QUOTE_DOUBLE_SPECIAL : switch( *line ) { case '\0' : /* Should not happen */ rc = SHELL_ERROR_PARSE_MISSING_QUOTE; break; case '\\' : case '\'' : case '"' : default : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else if( len == SHELL_MAX_TOKEN_LEN ) rc = SHELL_ERROR_PARSE_LONG_TOKEN; else { *s = *line; s++; len++; state = STATE_TOKENIZE_QUOTE_DOUBLE; } break; } break; case STATE_TOKENIZE_QUOTE_SINGLE_SPECIAL : switch( *line ) { case '\0' : /* Should not happen */ rc = SHELL_ERROR_PARSE_MISSING_QUOTE; break; case '\\' : case '\'' : case '"' : default : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else if( len == SHELL_MAX_TOKEN_LEN ) rc = SHELL_ERROR_PARSE_LONG_TOKEN; else { *s = *line; s++; len++; state = STATE_TOKENIZE_QUOTE_SINGLE; } break; } break; case STATE_TOKENIZE_WORD : switch( *line ) { case '\\' : state = STATE_TOKENIZE_WORD_SPECIAL; break; case '\'' : state = STATE_TOKENIZE_QUOTE_SINGLE; break; case '"' : state = STATE_TOKENIZE_QUOTE_DOUBLE; break; case '\0' : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else { *s = *line; argc++; state = STATE_TOKENIZE_DONE; } break; case ' ' : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else { *s = '\0'; argc++; s = argv[argc]; len = 0; state = STATE_TOKENIZE_SEARCH; } break; default : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else if( len == SHELL_MAX_TOKEN_LEN ) rc = SHELL_ERROR_PARSE_LONG_TOKEN; else { *s = *line; s++; len++; state = STATE_TOKENIZE_WORD; } break; } break; case STATE_TOKENIZE_WORD_SPECIAL : switch( *line ) { case '\0' : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else { *s = *line; argc++; state = STATE_TOKENIZE_DONE; } break; case '\\' : case '\'' : case '"' : default : if( argc == MAX_ARGC ) rc = SHELL_ERROR_PARSE_ARGCOUNT; else if( len == SHELL_MAX_TOKEN_LEN ) rc = SHELL_ERROR_PARSE_LONG_TOKEN; else { *s = *line; s++; len++; state = STATE_TOKENIZE_WORD; } break; } break; default : /* Should not happen */ rc = SHELL_ERROR_STRUCTURE; break; } line++; } while( (rc == OK) && (state != STATE_TOKENIZE_DONE) ); return rc;}/************************************************************************ * execute_command ************************************************************************/static UINT32execute_command( t_cmd **cmd ){ bool ambivalent; UINT32 rc; if( argc != 0 ) { *cmd = shell_lookup_cmd( argv[0], &ambivalent, NULL, command_list, command_count ); if( !(*cmd) ) { shell_error_data = argv[0]; return SHELL_ERROR_COMMAND_NOT_FOUND; } if( ambivalent ) { shell_error_data = argv[0]; return SHELL_ERROR_AMBIVALENT; } SHELL_ENABLE_MORE; if( !newline_after_prompt ) { SHELL_PUTC( '\n' ); newline_after_prompt = TRUE; } if( (strlen((*cmd)->name) == 1) && (*(*cmd)->name != '.') ) { /* Notify that this is a special Microsoft * SDB command. */ SHELL_PUTS( "Microsoft SDB Command\n" ); } /* We detect whether ctrl-c is typed during command execution */ ctrl_c_flag = FALSE; /* Execute command */ rc = (*cmd)->func( argc, &argv[0] ); SHELL_DISABLE_MORE; if( rc != OK ) return rc; } else ctrl_c_flag = FALSE; /* Test for CTRL-C in case command did not call shell_putc/s. */ if( !ctrl_c_flag ) ctrl_c_flag = GETCHAR_CTRLC( DEFAULT_PORT ); return ctrl_c_flag ? SHELL_ERROR_CONTROL_C_DETECTED : OK;}/************************************************************************ * execute_line ************************************************************************/static UINT32execute_line( char *line, /* Command line */ bool first ) /* First call (ie not recursively called) */{ char buffer[SHELL_MAX_COMMAND_LEN + 1]; char subcommand[SHELL_MAX_COMMAND_LEN + 1]; char *line_copy; char *first_subcommand; UINT32 count, subcommand_count; UINT32 repeat_count = 1; UINT32 rc; UINT32 len; t_cmd *cmd; line_copy = buffer; strcpy( line_copy, line ); /* Separate line in subcommands based on ';' characters */ separate( line_copy, &subcommand_count ); if( first ) { if( subcommand_count > 1 ) { /* Determine repeat (+<n>) count */ len = strlen(line_copy); if( get_repeat( line_copy, &repeat_count ) ) { line_copy = &line_copy[len + 1]; subcommand_count--; } } } first_subcommand = line_copy; do /* Loop based on repeat (+<n>) count */ { line_copy = first_subcommand; count = subcommand_count; do /* Perform each subcommand */ { strcpy( subcommand, line_copy ); cmd = NULL; if( first ) { /* Perform expansion of environment variables */ rc = expand_line( subcommand ); if( rc == OK ) { /* Execute the line */ rc = execute_line( subcommand, FALSE ); if( rc != OK ) return rc; } } else { rc = tokenize( subcommand ); if( rc == OK ) rc = execute_command( &cmd ); } if( rc != OK ) { if( !newline_after_prompt ) printf( "\n" ); shell_command_error( cmd, rc ); shell_error_data = NULL; shell_error_hint = NULL; } line_copy = &line_copy[strlen(line_copy) + 1]; } while( --count && (rc == OK) ); } while( ((repeat_count == 0) || --repeat_count) && (rc == OK) ); return rc;}/************************************************************************ * error_lookup ************************************************************************/static INT32 error_lookup( t_sys_error_string *param ){ UINT32 index = SYSERROR_ID( param->syserror ); if( index >= SHELL_ERROR_MSG_COUNT ) index = SHELL_ERROR_MSG_COUNT - 1; shell_error_msg[0] = '\0'; add2error( shell_err[index] ); if( shell_error_data ) { add2error( " : " ); add2error( shell_error_data ); shell_error_data = NULL; } if( (param->syserror == SHELL_ERROR_SYNTAX) && failing_cmd && (failing_cmd->syntax) ) { add2error( "\nSyntax :\n" ); add2error( failing_cmd->syntax ); } param->strings[SYSCON_ERRORMSG_IDX] = shell_error_msg; if( shell_error_hint ) { param->strings[SYSCON_DIAGMSG_IDX] = NULL; param->strings[SYSCON_HINTMSG_IDX] = shell_error_hint; param->count = 2; } else param->count = 1; return OK;}/************************************************************************ * add2error ************************************************************************/static voidadd2error( char *s ){ UINT32 len, count; len = strlen( shell_error_msg ); count = strlen(s); if( len + count + 1 > MAX_SHELL_ERR_MSG ) count = MAX_SHELL_ERR_MSG - len - 1; strncpy( &shell_error_msg[len], s, count ); shell_error_msg[len+count] = '\0';}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -