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

📄 subst.c

📁 android-w.song.android.widget
💻 C
📖 第 1 页 / 共 5 页
字号:
/* subst.c -- The part of the shell that does parameter, command, arithmetic,   and globbing substitutions. *//* ``Have a little faith, there's magic in the night.  You ain't a     beauty, but, hey, you're alright.'' *//* Copyright (C) 1987-2010 Free Software Foundation, Inc.   This file is part of GNU Bash, the Bourne Again SHell.   Bash is free software: you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation, either version 3 of the License, or   (at your option) any later version.   Bash is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with Bash.  If not, see <http://www.gnu.org/licenses/>.*/#include "config.h"#include "bashtypes.h"#include <stdio.h>#include "chartypes.h"#if defined (HAVE_PWD_H)#  include <pwd.h>#endif#include <signal.h>#include <errno.h>#if defined (HAVE_UNISTD_H)#  include <unistd.h>#endif#include "bashansi.h"#include "posixstat.h"#include "bashintl.h"#include "shell.h"#include "parser.h"#include "flags.h"#include "jobs.h"#include "execute_cmd.h"#include "filecntl.h"#include "trap.h"#include "pathexp.h"#include "mailcheck.h"#include "shmbutil.h"#include "typemax.h"#include "builtins/getopt.h"#include "builtins/common.h"#include "builtins/builtext.h"#include <tilde/tilde.h>#include <glob/strmatch.h>#if !defined (errno)extern int errno;#endif /* !errno *//* The size that strings change by. */#define DEFAULT_INITIAL_ARRAY_SIZE 112#define DEFAULT_ARRAY_SIZE 128/* Variable types. */#define VT_VARIABLE	0#define VT_POSPARMS	1#define VT_ARRAYVAR	2#define VT_ARRAYMEMBER	3#define VT_ASSOCVAR	4#define VT_STARSUB	128	/* $* or ${array[*]} -- used to split *//* Flags for quoted_strchr */#define ST_BACKSL	0x01#define ST_CTLESC	0x02#define ST_SQUOTE	0x04	/* unused yet */#define ST_DQUOTE	0x08	/* unused yet *//* Flags for the `pflags' argument to param_expand() */#define PF_NOCOMSUB	0x01	/* Do not perform command substitution */#define PF_IGNUNBOUND	0x02	/* ignore unbound vars even if -u set */#define PF_NOSPLIT2	0x04	/* same as W_NOSPLIT2 *//* These defs make it easier to use the editor. */#define LBRACE		'{'#define RBRACE		'}'#define LPAREN		'('#define RPAREN		')'#if defined (HANDLE_MULTIBYTE)#define WLPAREN		L'('#define WRPAREN		L')'#endif/* Evaluates to 1 if C is one of the shell's special parameters whose length   can be taken, but is also one of the special expansion characters. */#define VALID_SPECIAL_LENGTH_PARAM(c) \  ((c) == '-' || (c) == '?' || (c) == '#')/* Evaluates to 1 if C is one of the shell's special parameters for which an   indirect variable reference may be made. */#define VALID_INDIR_PARAM(c) \  ((posixly_correct == 0 && (c) == '#') || (posixly_correct == 0 && (c) == '?') || (c) == '@' || (c) == '*')/* Evaluates to 1 if C is one of the OP characters that follows the parameter   in ${parameter[:]OPword}. */#define VALID_PARAM_EXPAND_CHAR(c) (sh_syntaxtab[(unsigned char)c] & CSUBSTOP)/* Evaluates to 1 if this is one of the shell's special variables. */#define SPECIAL_VAR(name, wi) \ ((DIGIT (*name) && all_digits (name)) || \      (name[1] == '\0' && (sh_syntaxtab[(unsigned char)*name] & CSPECVAR)) || \      (wi && name[2] == '\0' && VALID_INDIR_PARAM (name[1])))/* An expansion function that takes a string and a quoted flag and returns   a WORD_LIST *.  Used as the type of the third argument to   expand_string_if_necessary(). */typedef WORD_LIST *EXPFUNC __P((char *, int));/* Process ID of the last command executed within command substitution. */pid_t last_command_subst_pid = NO_PID;pid_t current_command_subst_pid = NO_PID;/* Variables used to keep track of the characters in IFS. */SHELL_VAR *ifs_var;char *ifs_value;unsigned char ifs_cmap[UCHAR_MAX + 1];#if defined (HANDLE_MULTIBYTE)unsigned char ifs_firstc[MB_LEN_MAX];size_t ifs_firstc_len;#elseunsigned char ifs_firstc;#endif/* Sentinel to tell when we are performing variable assignments preceding a   command name and putting them into the environment.  Used to make sure   we use the temporary environment when looking up variable values. */int assigning_in_environment;/* Used to hold a list of variable assignments preceding a command.  Global   so the SIGCHLD handler in jobs.c can unwind-protect it when it runs a   SIGCHLD trap and so it can be saved and restored by the trap handlers. */WORD_LIST *subst_assign_varlist = (WORD_LIST *)NULL;/* Extern functions and variables from different files. */extern int last_command_exit_value, last_command_exit_signal;extern int subshell_environment, line_number;extern int subshell_level, parse_and_execute_level, sourcelevel;extern int eof_encountered;extern int return_catch_flag, return_catch_value;extern pid_t dollar_dollar_pid;extern int posixly_correct;extern char *this_command_name;extern struct fd_bitmap *current_fds_to_close;extern int wordexp_only;extern int expanding_redir;extern int tempenv_assign_error;#if !defined (HAVE_WCSDUP) && defined (HANDLE_MULTIBYTE)extern wchar_t *wcsdup __P((const wchar_t *));#endif/* Non-zero means to allow unmatched globbed filenames to expand to   a null file. */int allow_null_glob_expansion;/* Non-zero means to throw an error when globbing fails to match anything. */int fail_glob_expansion;#if 0/* Variables to keep track of which words in an expanded word list (the   output of expand_word_list_internal) are the result of globbing   expansions.  GLOB_ARGV_FLAGS is used by execute_cmd.c.   (CURRENTLY UNUSED). */char *glob_argv_flags;static int glob_argv_flags_size;#endifstatic WORD_LIST expand_word_error, expand_word_fatal;static WORD_DESC expand_wdesc_error, expand_wdesc_fatal;static char expand_param_error, expand_param_fatal;static char extract_string_error, extract_string_fatal;/* Tell the expansion functions to not longjmp back to top_level on fatal   errors.  Enabled when doing completion and prompt string expansion. */static int no_longjmp_on_fatal_error = 0;/* Set by expand_word_unsplit; used to inhibit splitting and re-joining   $* on $IFS, primarily when doing assignment statements. */static int expand_no_split_dollar_star = 0;/* A WORD_LIST of words to be expanded by expand_word_list_internal,   without any leading variable assignments. */static WORD_LIST *garglist = (WORD_LIST *)NULL;static char *quoted_substring __P((char *, int, int));static int quoted_strlen __P((char *));static char *quoted_strchr __P((char *, int, int));static char *expand_string_if_necessary __P((char *, int, EXPFUNC *));static inline char *expand_string_to_string_internal __P((char *, int, EXPFUNC *));static WORD_LIST *call_expand_word_internal __P((WORD_DESC *, int, int, int *, int *));static WORD_LIST *expand_string_internal __P((char *, int));static WORD_LIST *expand_string_leave_quoted __P((char *, int));static WORD_LIST *expand_string_for_rhs __P((char *, int, int *, int *));static WORD_LIST *list_quote_escapes __P((WORD_LIST *));static char *make_quoted_char __P((int));static WORD_LIST *quote_list __P((WORD_LIST *));static int unquoted_substring __P((char *, char *));static int unquoted_member __P((int, char *));#if defined (ARRAY_VARS)static SHELL_VAR *do_compound_assignment __P((char *, char *, int));#endifstatic int do_assignment_internal __P((const WORD_DESC *, int));static char *string_extract_verbatim __P((char *, size_t, int *, char *, int));static char *string_extract __P((char *, int *, char *, int));static char *string_extract_double_quoted __P((char *, int *, int));static inline char *string_extract_single_quoted __P((char *, int *));static inline int skip_single_quoted __P((const char *, size_t, int));static int skip_double_quoted __P((char *, size_t, int));static char *extract_delimited_string __P((char *, int *, char *, char *, char *, int));static char *extract_dollar_brace_string __P((char *, int *, int, int));static int skip_matched_pair __P((const char *, int, int, int, int));static char *pos_params __P((char *, int, int, int));static unsigned char *mb_getcharlens __P((char *, int));static char *remove_upattern __P((char *, char *, int));#if defined (HANDLE_MULTIBYTE) static wchar_t *remove_wpattern __P((wchar_t *, size_t, wchar_t *, int));#endifstatic char *remove_pattern __P((char *, char *, int));static int match_upattern __P((char *, char *, int, char **, char **));#if defined (HANDLE_MULTIBYTE)static int match_wpattern __P((wchar_t *, char **, size_t, wchar_t *, int, char **, char **));#endifstatic int match_pattern __P((char *, char *, int, char **, char **));static int getpatspec __P((int, char *));static char *getpattern __P((char *, int, int));static char *variable_remove_pattern __P((char *, char *, int, int));static char *list_remove_pattern __P((WORD_LIST *, char *, int, int, int));static char *parameter_list_remove_pattern __P((int, char *, int, int));#ifdef ARRAY_VARSstatic char *array_remove_pattern __P((SHELL_VAR *, char *, int, char *, int));#endifstatic char *parameter_brace_remove_pattern __P((char *, char *, int, char *, int, int, int));static char *process_substitute __P((char *, int));static char *read_comsub __P((int, int, int *));#ifdef ARRAY_VARSstatic arrayind_t array_length_reference __P((char *));#endifstatic int valid_brace_expansion_word __P((char *, int));static int chk_atstar __P((char *, int, int *, int *));static int chk_arithsub __P((const char *, int));static WORD_DESC *parameter_brace_expand_word __P((char *, int, int, int, arrayind_t *));static WORD_DESC *parameter_brace_expand_indir __P((char *, int, int, int *, int *));static WORD_DESC *parameter_brace_expand_rhs __P((char *, char *, int, int, int *, int *));static void parameter_brace_expand_error __P((char *, char *));static int valid_length_expression __P((char *));static intmax_t parameter_brace_expand_length __P((char *));static char *skiparith __P((char *, int));static int verify_substring_values __P((SHELL_VAR *, char *, char *, int, intmax_t *, intmax_t *));static int get_var_and_type __P((char *, char *, arrayind_t, int, int, SHELL_VAR **, char **));static char *mb_substring __P((char *, int, int));static char *parameter_brace_substring __P((char *, char *, int, char *, int, int));static int shouldexp_replacement __P((char *));static char *pos_params_pat_subst __P((char *, char *, char *, int));static char *parameter_brace_patsub __P((char *, char *, int, char *, int, int));static char *pos_params_casemod __P((char *, char *, int, int));static char *parameter_brace_casemod __P((char *, char *, int, int, char *, int, int));static WORD_DESC *parameter_brace_expand __P((char *, int *, int, int, int *, int *));static WORD_DESC *param_expand __P((char *, int *, int, int *, int *, int *, int *, int));static WORD_LIST *expand_word_internal __P((WORD_DESC *, int, int, int *, int *));static WORD_LIST *word_list_split __P((WORD_LIST *));static void exp_jump_to_top_level __P((int));static WORD_LIST *separate_out_assignments __P((WORD_LIST *));static WORD_LIST *glob_expand_word_list __P((WORD_LIST *, int));#ifdef BRACE_EXPANSIONstatic WORD_LIST *brace_expand_word_list __P((WORD_LIST *, int));#endif#if defined (ARRAY_VARS)static int make_internal_declare __P((char *, char *));#endifstatic WORD_LIST *shell_expand_word_list __P((WORD_LIST *, int));static WORD_LIST *expand_word_list_internal __P((WORD_LIST *, int));/* **************************************************************** *//*								    *//*			Utility Functions			    *//*								    *//* **************************************************************** */#if defined (DEBUG)voiddump_word_flags (flags)     int flags;{  int f;  f = flags;  fprintf (stderr, "%d -> ", f);  if (f & W_ASSIGNASSOC)    {      f &= ~W_ASSIGNASSOC;      fprintf (stderr, "W_ASSIGNASSOC%s", f ? "|" : "");    }  if (f & W_HASCTLESC)    {      f &= ~W_HASCTLESC;      fprintf (stderr, "W_HASCTLESC%s", f ? "|" : "");    }  if (f & W_NOPROCSUB)    {      f &= ~W_NOPROCSUB;      fprintf (stderr, "W_NOPROCSUB%s", f ? "|" : "");    }  if (f & W_DQUOTE)    {      f &= ~W_DQUOTE;      fprintf (stderr, "W_DQUOTE%s", f ? "|" : "");    }  if (f & W_HASQUOTEDNULL)    {      f &= ~W_HASQUOTEDNULL;      fprintf (stderr, "W_HASQUOTEDNULL%s", f ? "|" : "");    }  if (f & W_ASSIGNARG)    {      f &= ~W_ASSIGNARG;      fprintf (stderr, "W_ASSIGNARG%s", f ? "|" : "");    }  if (f & W_ASSNBLTIN)    {      f &= ~W_ASSNBLTIN;      fprintf (stderr, "W_ASSNBLTIN%s", f ? "|" : "");    }  if (f & W_COMPASSIGN)    {      f &= ~W_COMPASSIGN;      fprintf (stderr, "W_COMPASSIGN%s", f ? "|" : "");    }  if (f & W_NOEXPAND)    {      f &= ~W_NOEXPAND;      fprintf (stderr, "W_NOEXPAND%s", f ? "|" : "");    }  if (f & W_ITILDE)    {      f &= ~W_ITILDE;      fprintf (stderr, "W_ITILDE%s", f ? "|" : "");    }  if (f & W_NOTILDE)    {      f &= ~W_NOTILDE;      fprintf (stderr, "W_NOTILDE%s", f ? "|" : "");    }  if (f & W_ASSIGNRHS)    {      f &= ~W_ASSIGNRHS;      fprintf (stderr, "W_ASSIGNRHS%s", f ? "|" : "");    }  if (f & W_NOCOMSUB)    {      f &= ~W_NOCOMSUB;      fprintf (stderr, "W_NOCOMSUB%s", f ? "|" : "");    }  if (f & W_DOLLARSTAR)    {      f &= ~W_DOLLARSTAR;      fprintf (stderr, "W_DOLLARSTAR%s", f ? "|" : "");    }  if (f & W_DOLLARAT)    {      f &= ~W_DOLLARAT;      fprintf (stderr, "W_DOLLARAT%s", f ? "|" : "");    }  if (f & W_TILDEEXP)    {      f &= ~W_TILDEEXP;      fprintf (stderr, "W_TILDEEXP%s", f ? "|" : "");    }  if (f & W_NOSPLIT2)    {      f &= ~W_NOSPLIT2;      fprintf (stderr, "W_NOSPLIT2%s", f ? "|" : "");    }  if (f & W_NOGLOB)    {      f &= ~W_NOGLOB;      fprintf (stderr, "W_NOGLOB%s", f ? "|" : "");    }  if (f & W_NOSPLIT)    {      f &= ~W_NOSPLIT;      fprintf (stderr, "W_NOSPLIT%s", f ? "|" : "");    }  if (f & W_GLOBEXP)    {      f &= ~W_GLOBEXP;      fprintf (stderr, "W_GLOBEXP%s", f ? "|" : "");    }  if (f & W_ASSIGNMENT)    {      f &= ~W_ASSIGNMENT;      fprintf (stderr, "W_ASSIGNMENT%s", f ? "|" : "");    }  if (f & W_QUOTED)    {      f &= ~W_QUOTED;      fprintf (stderr, "W_QUOTED%s", f ? "|" : "");    }  if (f & W_HASDOLLAR)    {      f &= ~W_HASDOLLAR;      fprintf (stderr, "W_HASDOLLAR%s", f ? "|" : "");    }  fprintf (stderr, "\n");  fflush (stderr);}#endif#ifdef INCLUDE_UNUSEDstatic char *quoted_substring (string, start, end)     char *string;     int start, end;{  register int len, l;  register char *result, *s, *r;  len = end - start;  /* Move to string[start], skipping quoted characters. */  for (s = string, l = 0; *s && l < start; )    {      if (*s == CTLESC)	{	  s++;	  continue;	}      l++;      if (*s == 0)	break;    }  r = result = (char *)xmalloc (2*len + 1);      /* save room for quotes */  /* Copy LEN characters, including quote characters. */  s = string + l;  for (l = 0; l < len; s++)    {      if (*s == CTLESC)	*r++ = *s++;      *r++ = *s;      l++;      if (*s == 0)	break;    }  *r = '\0';  return result;}#endif

⌨️ 快捷键说明

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