?? cli-script.c
字號:
loop condition is nonzero. */voidwhile_command (char *arg, int from_tty){ struct command_line *command = NULL; control_level = 1; command = get_command_line (while_control, arg); if (command == NULL) return; execute_control_command (command); free_command_lines (&command);}/* "if" command support. Execute either the true or false arm depending on the value of the if conditional. */voidif_command (char *arg, int from_tty){ struct command_line *command = NULL; control_level = 1; command = get_command_line (if_control, arg); if (command == NULL) return; execute_control_command (command); free_command_lines (&command);}/* Cleanup */static voidarg_cleanup (void *ignore){ struct user_args *oargs = user_args; if (!user_args) internal_error (__FILE__, __LINE__, "arg_cleanup called with no user args.\n"); user_args = user_args->next; xfree (oargs);}/* Bind the incomming arguments for a user defined command to $arg0, $arg1 ... $argMAXUSERARGS. */static struct cleanup *setup_user_args (char *p){ struct user_args *args; struct cleanup *old_chain; unsigned int arg_count = 0; args = (struct user_args *) xmalloc (sizeof (struct user_args)); memset (args, 0, sizeof (struct user_args)); args->next = user_args; user_args = args; old_chain = make_cleanup (arg_cleanup, 0/*ignored*/); if (p == NULL) return old_chain; while (*p) { char *start_arg; int squote = 0; int dquote = 0; int bsquote = 0; if (arg_count >= MAXUSERARGS) { error ("user defined function may only have %d arguments.\n", MAXUSERARGS); return old_chain; } /* Strip whitespace. */ while (*p == ' ' || *p == '\t') p++; /* P now points to an argument. */ start_arg = p; user_args->a[arg_count].arg = p; /* Get to the end of this argument. */ while (*p) { if (((*p == ' ' || *p == '\t')) && !squote && !dquote && !bsquote) break; else { if (bsquote) bsquote = 0; else if (*p == '\\') bsquote = 1; else if (squote) { if (*p == '\'') squote = 0; } else if (dquote) { if (*p == '"') dquote = 0; } else { if (*p == '\'') squote = 1; else if (*p == '"') dquote = 1; } p++; } } user_args->a[arg_count].len = p - start_arg; arg_count++; user_args->count++; } return old_chain;}/* Given character string P, return a point to the first argument ($arg), or NULL if P contains no arguments. */static char *locate_arg (char *p){ while ((p = strchr (p, '$'))) { if (strncmp (p, "$arg", 4) == 0 && isdigit (p[4])) return p; p++; } return NULL;}/* Insert the user defined arguments stored in user_arg into the $arg arguments found in line, with the updated copy being placed into nline. */static char *insert_args (char *line){ char *p, *save_line, *new_line; unsigned len, i; /* First we need to know how much memory to allocate for the new line. */ save_line = line; len = 0; while ((p = locate_arg (line))) { len += p - line; i = p[4] - '0'; if (i >= user_args->count) { error ("Missing argument %d in user function.\n", i); return NULL; } len += user_args->a[i].len; line = p + 5; } /* Don't forget the tail. */ len += strlen (line); /* Allocate space for the new line and fill it in. */ new_line = (char *) xmalloc (len + 1); if (new_line == NULL) return NULL; /* Restore pointer to beginning of old line. */ line = save_line; /* Save pointer to beginning of new line. */ save_line = new_line; while ((p = locate_arg (line))) { int i, len; memcpy (new_line, line, p - line); new_line += p - line; i = p[4] - '0'; len = user_args->a[i].len; if (len) { memcpy (new_line, user_args->a[i].arg, len); new_line += len; } line = p + 5; } /* Don't forget the tail. */ strcpy (new_line, line); /* Return a pointer to the beginning of the new line. */ return save_line;}/* Expand the body_list of COMMAND so that it can hold NEW_LENGTH code bodies. This is typically used when we encounter an "else" clause for an "if" command. */static voidrealloc_body_list (struct command_line *command, int new_length){ int n; struct command_line **body_list; n = command->body_count; /* Nothing to do? */ if (new_length <= n) return; body_list = (struct command_line **) xmalloc (sizeof (struct command_line *) * new_length); memcpy (body_list, command->body_list, sizeof (struct command_line *) * n); xfree (command->body_list); command->body_list = body_list; command->body_count = new_length;}/* Read one line from the input stream. If the command is an "else" or "end", return such an indication to the caller. */static enum misc_command_typeread_next_line (struct command_line **command){ char *p, *p1, *prompt_ptr, control_prompt[256]; int i = 0; if (control_level >= 254) error ("Control nesting too deep!\n"); /* Set a prompt based on the nesting of the control commands. */ if (instream == stdin || (instream == 0 && deprecated_readline_hook != NULL)) { for (i = 0; i < control_level; i++) control_prompt[i] = ' '; control_prompt[i] = '>'; control_prompt[i + 1] = '\0'; prompt_ptr = (char *) &control_prompt[0]; } else prompt_ptr = NULL; p = command_line_input (prompt_ptr, instream == stdin, "commands"); /* Not sure what to do here. */ if (p == NULL) return end_command; /* Strip leading and trailing whitespace. */ while (*p == ' ' || *p == '\t') p++; p1 = p + strlen (p); while (p1 != p && (p1[-1] == ' ' || p1[-1] == '\t')) p1--; /* Blanks and comments don't really do anything, but we need to distinguish them from else, end and other commands which can be executed. */ if (p1 == p || p[0] == '#') return nop_command; /* Is this the end of a simple, while, or if control structure? */ if (p1 - p == 3 && !strncmp (p, "end", 3)) return end_command; /* Is the else clause of an if control structure? */ if (p1 - p == 4 && !strncmp (p, "else", 4)) return else_command; /* Check for while, if, break, continue, etc and build a new command line structure for them. */ if (p1 - p > 5 && !strncmp (p, "while", 5)) { char *first_arg; first_arg = p + 5; while (first_arg < p1 && isspace (*first_arg)) first_arg++; *command = build_command_line (while_control, first_arg); } else if (p1 - p > 2 && !strncmp (p, "if", 2)) { char *first_arg; first_arg = p + 2; while (first_arg < p1 && isspace (*first_arg)) first_arg++; *command = build_command_line (if_control, first_arg); } else if (p1 - p == 10 && !strncmp (p, "loop_break", 10)) { *command = (struct command_line *) xmalloc (sizeof (struct command_line)); (*command)->next = NULL; (*command)->line = NULL; (*command)->control_type = break_control; (*command)->body_count = 0; (*command)->body_list = NULL; } else if (p1 - p == 13 && !strncmp (p, "loop_continue", 13)) { *command = (struct command_line *) xmalloc (sizeof (struct command_line)); (*command)->next = NULL; (*command)->line = NULL; (*command)->control_type = continue_control; (*command)->body_count = 0; (*command)->body_list = NULL; } else { /* A normal command. */ *command = (struct command_line *) xmalloc (sizeof (struct command_line)); (*command)->next = NULL; (*command)->line = savestring (p, p1 - p); (*command)->control_type = simple_control; (*command)->body_count = 0; (*command)->body_list = NULL; } /* Nothing special. */ return ok_command;}/* Recursively read in the control structures and create a command_line structure from them. The parent_control parameter is the control structure in which the following commands are nested. */static enum command_control_typerecurse_read_control_structure (struct command_line *current_cmd){ int current_body, i; enum misc_command_type val; enum command_control_type ret; struct command_line **body_ptr, *child_tail, *next; child_tail = NULL; current_body = 1; /* Sanity checks. */ if (current_cmd->control_type == simple_control) { error ("Recursed on a simple control type\n"); return invalid_control; } if (current_body > current_cmd->body_count) { error ("Allocated body is smaller than this command type needs\n"); return invalid_control; } /* Read lines from the input stream and build control structures. */ while (1) { dont_repeat (); next = NULL; val = read_next_line (&next); /* Just skip blanks and comments. */ if (val == nop_command) continue; if (val == end_command) { if (current_cmd->control_type == while_control || current_cmd->control_type == if_control) { /* Success reading an entire control structure. */ ret = simple_control; break; } else { ret = invalid_control; break; } } /* Not the end of a control structure. */ if (val == else_command) { if (current_cmd->control_type == if_control && current_body == 1) { realloc_body_list (current_cmd, 2); current_body = 2; child_tail = NULL; continue; } else { ret = invalid_control; break; } } if (child_tail) { child_tail->next = next; } else { body_ptr = current_cmd->body_list; for (i = 1; i < current_body; i++) body_ptr++; *body_ptr = next; } child_tail = next; /* If the latest line is another control structure, then recurse on it. */ if (next->control_type == while_control || next->control_type == if_control) { control_level++;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -