Bash-4.3 distribution sources and documentation
This commit is contained in:
		
					parent
					
						
							
								4539d736f1
							
						
					
				
			
			
				commit
				
					
						ac50fbac37
					
				
			
		
					 497 changed files with 129395 additions and 87598 deletions
				
			
		|  | @ -92,7 +92,7 @@ CSOURCES = clktck.c clock.c getcwd.c getenv.c oslib.c setlinebuf.c \ | |||
| 	   mktime.c strftime.c mbschr.c zcatfd.c zmapfd.c winsize.c eaccess.c \
 | ||||
| 	   wcsdup.c fpurge.c zgetline.c mbscmp.c uconvert.c ufuncs.c \
 | ||||
| 	   casemod.c dprintf.c input_avail.c mbscasecmp.c fnxform.c \
 | ||||
| 	   strchrnul.c unicode.c wcswidth.c shmbchar.c | ||||
| 	   strchrnul.c unicode.c wcswidth.c wcsnwidth.c shmbchar.c strdup.c | ||||
| 
 | ||||
| # The header files for this library.
 | ||||
| HSOURCES =  | ||||
|  | @ -106,7 +106,8 @@ OBJECTS = clktck.o clock.o getenv.o oslib.o setlinebuf.o strnlen.o \ | |||
| 	  strtrans.o snprintf.o mailstat.o fmtulong.o \
 | ||||
| 	  fmtullong.o fmtumax.o zcatfd.o zmapfd.o winsize.o wcsdup.o \
 | ||||
| 	  fpurge.o zgetline.o mbscmp.o uconvert.o ufuncs.o casemod.o \
 | ||||
| 	  input_avail.o mbscasecmp.o fnxform.o unicode.o shmbchar.o ${LIBOBJS} | ||||
| 	  input_avail.o mbscasecmp.o fnxform.o unicode.o shmbchar.o \
 | ||||
| 	  wcsnwidth.o ${LIBOBJS} | ||||
| 
 | ||||
| SUPPORT = Makefile | ||||
| 
 | ||||
|  | @ -197,6 +198,7 @@ uconvert.o: uconvert.c | |||
| ufuncs.o: ufuncs.c | ||||
| vprint.o: vprint.c | ||||
| wcsdup.o: wcsdup.c | ||||
| wcsnwidth.o: wcsnwidth.c | ||||
| wcswidth.o: wcswidth.c | ||||
| mbschr.o: mbschr.c | ||||
| zcatfd.o: zcatfd.c | ||||
|  | @ -269,6 +271,7 @@ uconvert.o: ${BUILD_DIR}/config.h | |||
| ufuncs.o: ${BUILD_DIR}/config.h | ||||
| vprint.o: ${BUILD_DIR}/config.h | ||||
| wcsdup.o: ${BUILD_DIR}/config.h | ||||
| wcsnwidth.o: ${BUILD_DIR}/config.h | ||||
| wcswidth.o: ${BUILD_DIR}/config.h | ||||
| mbschr.o: ${BUILD_DIR}/config.h | ||||
| zcatfd.o: ${BUILD_DIR}/config.h | ||||
|  | @ -291,7 +294,7 @@ getenv.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | |||
| getenv.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| getenv.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| getenv.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| getenv.o: ${BUILD_DIR}/version.h | ||||
| #getenv.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| inet_aton.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h | ||||
| inet_aton.o: ${BASHINCDIR}/stdc.h | ||||
|  | @ -303,7 +306,8 @@ itos.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdir | |||
| itos.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| itos.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| itos.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| itos.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| itos.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| #itos.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| makepath.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h | ||||
| makepath.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h | ||||
|  | @ -312,7 +316,8 @@ makepath.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${to | |||
| makepath.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| makepath.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| makepath.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| makepath.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| makepath.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| #makepath.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| netconn.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h | ||||
| netconn.o: ${topdir}/bashtypes.h | ||||
|  | @ -324,8 +329,9 @@ netopen.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${top | |||
| netopen.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| netopen.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| netopen.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| netopen.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| netopen.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| netopen.o: ${topdir}/bashintl.h ${LIBINTL_H} $(BASHINCDIR)/gettext.h | ||||
| #netopen.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| oslib.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h | ||||
| oslib.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h | ||||
|  | @ -334,9 +340,10 @@ oslib.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${topdi | |||
| oslib.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| oslib.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| oslib.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| oslib.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| oslib.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| oslib.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h | ||||
| oslib.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h | ||||
| #oslib.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| pathcanon.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h | ||||
| pathcanon.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h | ||||
|  | @ -345,9 +352,10 @@ pathcanon.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${t | |||
| pathcanon.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| pathcanon.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| pathcanon.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| pathcanon.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| pathcanon.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| pathcanon.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h | ||||
| pathcanon.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h | ||||
| #pathcanon.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| pathphys.o: ${topdir}/bashtypes.h ${topdir}/bashansi.h ${BASHINCDIR}/maxpath.h | ||||
| pathphys.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h | ||||
|  | @ -356,9 +364,10 @@ pathphys.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${to | |||
| pathphys.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| pathphys.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| pathphys.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| pathphys.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| pathphys.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| pathphys.o: ${BASHINCDIR}/posixstat.h ${BASHINCDIR}/filecntl.h | ||||
| pathphys.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h | ||||
| #pathphys.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| rename.o: ${topdir}/bashtypes.h ${BASHINCDIR}/stdc.h | ||||
| rename.o: ${BASHINCDIR}/posixstat.h | ||||
|  | @ -377,7 +386,8 @@ eaccess.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${top | |||
| eaccess.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| eaccess.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| eaccess.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| eaccess.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| eaccess.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| #eaccess.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| shquote.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h | ||||
| shquote.o: ${BASHINCDIR}/ansi_stdlib.h ${topdir}/xmalloc.h | ||||
|  | @ -403,7 +413,8 @@ strerror.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${to | |||
| strerror.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| strerror.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| strerror.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| strerror.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| strerror.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| #strerror.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| strcasestr.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h | ||||
| strcasestr.o: ${BASHINCDIR}/ansi_stdlib.h ${BASHINCDIR}/chartypes.h | ||||
|  | @ -415,7 +426,8 @@ stringlist.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${ | |||
| stringlist.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| stringlist.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| stringlist.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| stringlist.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| stringlist.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| #stringlist.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| stringvec.o: ${topdir}/bashansi.h ${BASHINCDIR}/chartypes.h | ||||
| stringvec.o: ${topdir}/shell.h ${topdir}/syntax.h ${topdir}/bashjmp.h ${BASHINCDIR}/posixjmp.h | ||||
|  | @ -424,7 +436,8 @@ stringvec.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${t | |||
| stringvec.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| stringvec.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| stringvec.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| stringvec.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| stringvec.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| #stringvec.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| strnlen.o: ${BASHINCDIR}/stdc.h | ||||
| 
 | ||||
|  | @ -461,7 +474,8 @@ strtrans.o: ${topdir}/general.h ${topdir}/bashtypes.h ${topdir}/variables.h ${to | |||
| strtrans.o: ${topdir}/array.h ${topdir}/hashlib.h ${topdir}/quit.h | ||||
| strtrans.o: ${topdir}/unwind_prot.h ${topdir}/dispose_cmd.h | ||||
| strtrans.o: ${topdir}/make_cmd.h ${topdir}/subst.h ${topdir}/sig.h | ||||
| strtrans.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h ${BUILD_DIR}/version.h | ||||
| strtrans.o: ${BUILD_DIR}/pathnames.h ${topdir}/externs.h | ||||
| #strtrans.o: ${BUILD_DIR}/version.h
 | ||||
| 
 | ||||
| times.o: ${BASHINCDIR}/systimes.h | ||||
| times.o: ${BASHINCDIR}/posixtime.h | ||||
|  | @ -510,6 +524,9 @@ wcsdup.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h | |||
| wcsdup.o: ${BASHINCDIR}/stdc.h | ||||
| wcsdup.o: ${topdir}/xmalloc.h | ||||
| 
 | ||||
| wcsnwidth.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h | ||||
| wcsnwidth.o: ${BASHINCDIR}/stdc.h | ||||
| 
 | ||||
| wcswidth.o: ${topdir}/bashansi.h ${BASHINCDIR}/ansi_stdlib.h | ||||
| wcswidth.o: ${BASHINCDIR}/stdc.h | ||||
| 
 | ||||
|  |  | |||
|  | @ -36,8 +36,10 @@ | |||
| #include <ctype.h> | ||||
| #include <xmalloc.h> | ||||
| 
 | ||||
| #include <shmbchar.h> | ||||
| #include <shmbutil.h> | ||||
| #include <chartypes.h> | ||||
| #include <typemax.h> | ||||
| 
 | ||||
| #include <glob/strmatch.h> | ||||
| 
 | ||||
|  | @ -67,6 +69,10 @@ | |||
| 
 | ||||
| extern char *substring __P((char *, int, int)); | ||||
| 
 | ||||
| #ifndef UCHAR_MAX | ||||
| #  define UCHAR_MAX	TYPE_MAXIMUM(unsigned char) | ||||
| #endif | ||||
| 
 | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
| static wchar_t | ||||
| cval (s, i) | ||||
|  | @ -78,7 +84,7 @@ cval (s, i) | |||
|   int l; | ||||
|   mbstate_t mps;   | ||||
| 
 | ||||
|   if (MB_CUR_MAX == 1) | ||||
|   if (MB_CUR_MAX == 1 || is_basic (s[i])) | ||||
|     return ((wchar_t)s[i]); | ||||
|   l = strlen (s); | ||||
|   if (i >= (l - 1)) | ||||
|  | @ -140,8 +146,10 @@ sh_modcase (string, pat, flags) | |||
|       if (iswalnum (wc) == 0) | ||||
| 	{ | ||||
| 	  inword = 0; | ||||
| #if 0 | ||||
| 	  ADVANCE_CHAR (ret, end, start); | ||||
| 	  continue; | ||||
| #endif | ||||
| 	} | ||||
| 
 | ||||
|       if (pat) | ||||
|  | @ -202,8 +210,11 @@ sh_modcase (string, pat, flags) | |||
|       else | ||||
| 	nop = flags; | ||||
| 
 | ||||
|       if (MB_CUR_MAX == 1 || isascii (wc)) | ||||
|       /* Need to check UCHAR_MAX since wc may have already been converted to a
 | ||||
| 	 wide character by cval() */ | ||||
|       if (MB_CUR_MAX == 1 || (wc <= UCHAR_MAX && is_basic ((int)wc))) | ||||
| 	{ | ||||
| singlebyte: | ||||
| 	  switch (nop) | ||||
| 	  { | ||||
| 	  default: | ||||
|  | @ -220,15 +231,18 @@ sh_modcase (string, pat, flags) | |||
| 	{ | ||||
| 	  m = mbrtowc (&wc, string + start, end - start, &state); | ||||
| 	  if (MB_INVALIDCH (m)) | ||||
| 	    wc = (wchar_t)string[start]; | ||||
| 	    { | ||||
| 	      wc = (unsigned char)string[start]; | ||||
| 	      goto singlebyte; | ||||
| 	    } | ||||
| 	  else if (MB_NULLWCH (m)) | ||||
| 	    wc = L'\0'; | ||||
| 	  switch (nop) | ||||
| 	  { | ||||
| 	  default: | ||||
| 	  case CASE_NOOP:  nwc = wc; break; | ||||
| 	  case CASE_UPPER:  nwc = TOUPPER (wc); break; | ||||
| 	  case CASE_LOWER:  nwc = TOLOWER (wc); break; | ||||
| 	  case CASE_UPPER:  nwc = _to_wupper (wc); break; | ||||
| 	  case CASE_LOWER:  nwc = _to_wlower (wc); break; | ||||
| 	  case CASE_TOGGLEALL: | ||||
| 	  case CASE_TOGGLE: nwc = TOGGLE (wc); break; | ||||
| 	  } | ||||
|  |  | |||
|  | @ -21,7 +21,9 @@ | |||
| #include <config.h> | ||||
| 
 | ||||
| #include <bashtypes.h> | ||||
| #include <sys/param.h> | ||||
| #if defined (HAVE_SYS_PARAM_H) | ||||
| #  include <sys/param.h> | ||||
| #endif | ||||
| 
 | ||||
| #if defined (HAVE_UNISTD_H) | ||||
| #  include <unistd.h> | ||||
|  |  | |||
|  | @ -205,14 +205,16 @@ sh_eaccess (path, mode) | |||
|   if (path_is_devfd (path)) | ||||
|     return (sh_stataccess (path, mode)); | ||||
| 
 | ||||
| #if defined (HAVE_FACCESSAT) && defined (AT_EACCESS) | ||||
|   return (faccessat (AT_FDCWD, path, mode, AT_EACCESS)); | ||||
| #elif defined (HAVE_EACCESS)		/* FreeBSD */ | ||||
| #if (defined (HAVE_FACCESSAT) && defined (AT_EACCESS)) || defined (HAVE_EACCESS) | ||||
| #  if defined (HAVE_FACCESSAT) && defined (AT_EACCESS) | ||||
|   ret = faccessat (AT_FDCWD, path, mode, AT_EACCESS); | ||||
| #  else		/* HAVE_EACCESS */	/* FreeBSD */ | ||||
|   ret = eaccess (path, mode);	/* XXX -- not always correct for X_OK */ | ||||
| #  if defined (__FreeBSD__) | ||||
| #  endif	/* HAVE_EACCESS */ | ||||
| #  if defined (__FreeBSD__) || defined (SOLARIS) | ||||
|   if (ret == 0 && current_user.euid == 0 && mode == X_OK) | ||||
|     return (sh_stataccess (path, mode)); | ||||
| #  endif | ||||
| #  endif	/* __FreeBSD__ || SOLARIS */ | ||||
|   return ret; | ||||
| #elif defined (EFF_ONLY_OK)		/* SVR4(?), SVR4.2 */ | ||||
|   return access (path, mode|EFF_ONLY_OK); | ||||
|  | @ -233,7 +235,6 @@ sh_eaccess (path, mode) | |||
| 	return (sh_stataccess (path, mode)); | ||||
| #endif | ||||
|       return ret; | ||||
|        | ||||
|     } | ||||
| 
 | ||||
|   return (sh_stataccess (path, mode)); | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* fmtulong.c -- Convert unsigned long int to string. */ | ||||
| 
 | ||||
| /* Copyright (C) 1998-2002 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 1998-2011 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of GNU Bash, the Bourne Again SHell. | ||||
| 
 | ||||
|  | @ -98,8 +98,9 @@ fmtulong (ui, base, buf, len, flags) | |||
|   if (base < 2 || base > 64) | ||||
|     { | ||||
| #if 1 | ||||
|       /* XXX - truncation possible with long translation */ | ||||
|       strncpy (buf, _("invalid base"), len - 1); | ||||
|       buf[len] = '\0'; | ||||
|       buf[len-1] = '\0'; | ||||
|       errno = EINVAL; | ||||
|       return (p = buf); | ||||
| #else | ||||
|  |  | |||
|  | @ -48,7 +48,7 @@ | |||
| 
 | ||||
| #include <bashansi.h> | ||||
| 
 | ||||
| #if defined (BROKEN_DIRENT_D_INO) | ||||
| #if !defined (D_FILENO_AVAILABLE) | ||||
| #  include "command.h" | ||||
| #  include "general.h" | ||||
| #  include "externs.h" | ||||
|  | @ -71,7 +71,7 @@ extern int errno; | |||
| /* If the d_fileno member of a struct dirent doesn't return anything useful,
 | ||||
|    we need to check inode number equivalence the hard way.  Return 1 if | ||||
|    the inode corresponding to PATH/DIR is identical to THISINO. */ | ||||
| #if defined (BROKEN_DIRENT_D_INO) | ||||
| #if !defined (D_FILENO_AVAILABLE) | ||||
| static int | ||||
| _path_checkino (dotp, name, thisino) | ||||
|      char *dotp; | ||||
|  | @ -206,7 +206,7 @@ getcwd (buf, size) | |||
| 	      (d->d_name[1] == '\0' || | ||||
| 		(d->d_name[1] == '.' && d->d_name[2] == '\0'))) | ||||
| 	    continue; | ||||
| #if !defined (BROKEN_DIRENT_D_INO) | ||||
| #if defined (D_FILENO_AVAILABLE) | ||||
| 	  if (mount_point || d->d_fileno == thisino) | ||||
| #else | ||||
| 	  if (mount_point || _path_checkino (dotp, d->d_name, thisino)) | ||||
|  |  | |||
|  | @ -67,7 +67,9 @@ static char rcsid[] = "$Id: inet_addr.c,v 1.5 1996/08/14 03:48:37 drepper Exp $" | |||
| #if !defined (HAVE_INET_ATON) && defined (HAVE_NETWORK) && defined (HAVE_NETINET_IN_H) && defined (HAVE_ARPA_INET_H) | ||||
| 
 | ||||
| #include <sys/types.h> | ||||
| #if defined (HAVE_SYS_PARAM_H) | ||||
| #include <sys/param.h> | ||||
| #endif | ||||
| #include <netinet/in.h> | ||||
| #include <arpa/inet.h> | ||||
| 
 | ||||
|  |  | |||
|  | @ -50,6 +50,18 @@ itos (i) | |||
|   return (savestring (p)); | ||||
| } | ||||
| 
 | ||||
| /* Integer to string conversion.  This conses the string using strdup;
 | ||||
|    caller should free it and be prepared to deal with NULL return. */ | ||||
| char * | ||||
| mitos (i) | ||||
|      intmax_t i; | ||||
| { | ||||
|   char *p, lbuf[INT_STRLEN_BOUND(intmax_t) + 1]; | ||||
| 
 | ||||
|   p = fmtumax (i, 10, lbuf, sizeof(lbuf), 0); | ||||
|   return (strdup (p)); | ||||
| } | ||||
| 
 | ||||
| char * | ||||
| uinttostr (i, buf, len) | ||||
|      uintmax_t i; | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ | |||
| #include <posixdir.h> | ||||
| #include <bashansi.h> | ||||
| 
 | ||||
| #ifndef _MINIX | ||||
| #if defined (HAVE_SYS_PARAM_H) | ||||
| #  include <sys/param.h> | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -94,7 +94,7 @@ sh_makepath (path, dir, flags) | |||
| 	MAKEDOT(); | ||||
|     } | ||||
|   else if ((flags & MP_IGNDOT) && path[0] == '.' && (path[1] == '\0' || | ||||
| 						     path[1] == '/' && path[2] == '\0')) | ||||
| 						     (path[1] == '/' && path[2] == '\0'))) | ||||
|     { | ||||
|       xpath = nullpath; | ||||
|       pathlen = 0; | ||||
|  |  | |||
|  | @ -27,6 +27,8 @@ | |||
| #include "bashansi.h" | ||||
| #include "shmbutil.h" | ||||
| 
 | ||||
| extern int locale_mb_cur_max; | ||||
| 
 | ||||
| #undef mbschr | ||||
| 
 | ||||
| /* In some locales, the non-first byte of some multibyte characters have
 | ||||
|  | @ -51,7 +53,7 @@ mbschr (s, c) | |||
|      GBK, GB18030, SHIFT_JIS, and JOHAB.  They exhibit the problem only | ||||
|      when c >= 0x30.  We can therefore use the faster bytewise search if | ||||
|      c <= 0x30. */ | ||||
|   if ((unsigned char)c >= '0' && MB_CUR_MAX > 1) | ||||
|   if ((unsigned char)c >= '0' && locale_mb_cur_max > 1) | ||||
|     { | ||||
|       pos = (char *)s; | ||||
|       memset (&state, '\0', sizeof(mbstate_t)); | ||||
|  | @ -59,9 +61,14 @@ mbschr (s, c) | |||
| 
 | ||||
|       while (strlength > 0) | ||||
| 	{ | ||||
| 	  mblength = mbrlen (pos, strlength, &state); | ||||
| 	  if (mblength == (size_t)-2 || mblength == (size_t)-1 || mblength == (size_t)0) | ||||
| 	  if (is_basic (*pos)) | ||||
| 	    mblength = 1; | ||||
| 	  else | ||||
| 	    { | ||||
| 	      mblength = mbrlen (pos, strlength, &state); | ||||
| 	      if (mblength == (size_t)-2 || mblength == (size_t)-1 || mblength == (size_t)0) | ||||
| 	        mblength = 1; | ||||
| 	    } | ||||
| 
 | ||||
| 	  if (mblength == 1 && c == (unsigned char)*pos) | ||||
| 	    return pos; | ||||
|  |  | |||
|  | @ -41,8 +41,6 @@ | |||
| 
 | ||||
| #ifndef VMS | ||||
| #include <sys/types.h>		/* Some systems define `time_t' here.  */ | ||||
| #else | ||||
| #include <stddef.h> | ||||
| #endif | ||||
| #include <time.h> | ||||
| 
 | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ | |||
| #include <config.h> | ||||
| 
 | ||||
| #include <bashtypes.h> | ||||
| #ifndef _MINIX | ||||
| #if defined (HAVE_SYS_PARAM_H) | ||||
| #  include <sys/param.h> | ||||
| #endif | ||||
| 
 | ||||
|  | @ -124,7 +124,7 @@ dup2 (fd1, fd2) | |||
| /*
 | ||||
|  * Return the total number of available file descriptors. | ||||
|  * | ||||
|  * On some systems, like 4.2BSD and its descendents, there is a system call | ||||
|  * On some systems, like 4.2BSD and its descendants, there is a system call | ||||
|  * that returns the size of the descriptor table: getdtablesize().  There are | ||||
|  * lots of ways to emulate this on non-BSD systems. | ||||
|  * | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ | |||
| #include <config.h> | ||||
| 
 | ||||
| #include <bashtypes.h> | ||||
| #ifndef _MINIX | ||||
| #if defined (HAVE_SYS_PARAM_H) | ||||
| #  include <sys/param.h> | ||||
| #endif | ||||
| #include <posixstat.h> | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ | |||
| #include <config.h> | ||||
| 
 | ||||
| #include <bashtypes.h> | ||||
| #ifndef _MINIX | ||||
| #if defined (HAVE_SYS_PARAM_H) | ||||
| #  include <sys/param.h> | ||||
| #endif | ||||
| #include <posixstat.h> | ||||
|  | @ -269,7 +269,7 @@ sh_realpath (pathname, resolved) | |||
|       wd = get_working_directory ("sh_realpath"); | ||||
|       if (wd == 0) | ||||
| 	return ((char *)NULL); | ||||
|       tdir = sh_makepath ((char *)pathname, wd, 0); | ||||
|       tdir = sh_makepath (wd, (char *)pathname, 0); | ||||
|       free (wd); | ||||
|     } | ||||
|   else | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| /* Copyright (C) 2001, 2006, 2009, 2010 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 2001, 2006, 2009, 2010, 2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This program is free software: you can redistribute it and/or modify | ||||
|    it under the terms of the GNU General Public License as published by | ||||
|  | @ -89,4 +89,25 @@ mbsmbchar (s) | |||
|     } | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| int | ||||
| sh_mbsnlen(src, srclen, maxlen) | ||||
|      const char *src; | ||||
|      size_t srclen; | ||||
|      int maxlen; | ||||
| { | ||||
|   int count; | ||||
|   int sind; | ||||
|   DECLARE_MBSTATE; | ||||
| 
 | ||||
|   for (sind = count = 0; src[sind]; ) | ||||
|     { | ||||
|       count++;		/* number of multibyte characters */ | ||||
|       ADVANCE_CHAR (src, srclen, sind); | ||||
|       if (sind > maxlen) | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|   return count; | ||||
| } | ||||
| #endif | ||||
|  |  | |||
							
								
								
									
										109
									
								
								lib/sh/shquote.c
									
										
									
									
									
								
							
							
						
						
									
										109
									
								
								lib/sh/shquote.c
									
										
									
									
									
								
							|  | @ -32,6 +32,50 @@ | |||
| #include "syntax.h" | ||||
| #include <xmalloc.h> | ||||
| 
 | ||||
| /* Default set of characters that should be backslash-quoted in strings */ | ||||
| static const char bstab[256] = | ||||
|   { | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 1, 1, 0, 0, 0, 0, 0,	/* TAB, NL */ | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
| 
 | ||||
|     1, 1, 1, 0, 1, 0, 1, 1,	/* SPACE, !, DQUOTE, DOL, AMP, SQUOTE */ | ||||
|     1, 1, 1, 0, 1, 0, 0, 0,	/* LPAR, RPAR, STAR, COMMA */ | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 1, 1, 0, 1, 1,	/* SEMI, LESSTHAN, GREATERTHAN, QUEST */ | ||||
| 
 | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 1, 1, 1, 1, 0,	/* LBRACK, BS, RBRACK, CARAT */ | ||||
| 
 | ||||
|     1, 0, 0, 0, 0, 0, 0, 0,	/* BACKQ */ | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 1, 1, 1, 0, 0,	/* LBRACE, BAR, RBRACE */ | ||||
| 
 | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
| 
 | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
| 
 | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
| 
 | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|     0, 0, 0, 0, 0, 0, 0, 0, | ||||
|   }; | ||||
| 
 | ||||
| /* **************************************************************** */ | ||||
| /*								    */ | ||||
| /*	 Functions for quoting strings to be re-read as input	    */ | ||||
|  | @ -50,6 +94,15 @@ sh_single_quote (string) | |||
| 
 | ||||
|   result = (char *)xmalloc (3 + (4 * strlen (string))); | ||||
|   r = result; | ||||
| 
 | ||||
|   if (string[0] == '\'' && string[1] == 0) | ||||
|     { | ||||
|       *r++ = '\\'; | ||||
|       *r++ = '\''; | ||||
|       *r++ = 0; | ||||
|       return result; | ||||
|     } | ||||
| 
 | ||||
|   *r++ = '\''; | ||||
| 
 | ||||
|   for (s = string; s && (c = *s); s++) | ||||
|  | @ -163,53 +216,33 @@ sh_un_double_quote (string) | |||
|    way to protect the CTLESC and CTLNUL characters.  As I write this, | ||||
|    the current callers will never cause the string to be expanded without | ||||
|    going through the shell parser, which will protect the internal | ||||
|    quoting characters. */ | ||||
|    quoting characters.  TABLE, if set, points to a map of the ascii code | ||||
|    set with char needing to be backslash-quoted if table[char]==1.  FLAGS, | ||||
|    if 1, causes tildes to be quoted as well. */ | ||||
|     | ||||
| char * | ||||
| sh_backslash_quote (string) | ||||
| sh_backslash_quote (string, table, flags) | ||||
|      char *string; | ||||
|      char *table; | ||||
|      int flags; | ||||
| { | ||||
|   int c; | ||||
|   char *result, *r, *s; | ||||
|   char *result, *r, *s, *backslash_table; | ||||
| 
 | ||||
|   result = (char *)xmalloc (2 * strlen (string) + 1); | ||||
| 
 | ||||
|   backslash_table = table ? table : (char *)bstab; | ||||
|   for (r = result, s = string; s && (c = *s); s++) | ||||
|     { | ||||
|       switch (c) | ||||
| 	{ | ||||
| 	case ' ': case '\t': case '\n':		/* IFS white space */ | ||||
| 	case '\'': case '"': case '\\':		/* quoting chars */ | ||||
| 	case '|': case '&': case ';':		/* shell metacharacters */ | ||||
| 	case '(': case ')': case '<': case '>': | ||||
| 	case '!': case '{': case '}':		/* reserved words */ | ||||
| 	case '*': case '[': case '?': case ']':	/* globbing chars */ | ||||
| 	case '^': | ||||
| 	case '$': case '`':			/* expansion chars */ | ||||
| 	case ',':				/* brace expansion */ | ||||
| 	  *r++ = '\\'; | ||||
| 	  *r++ = c; | ||||
| 	  break; | ||||
| #if 0 | ||||
| 	case '~':				/* tilde expansion */ | ||||
| 	  if (s == string || s[-1] == '=' || s[-1] == ':') | ||||
| 	    *r++ = '\\'; | ||||
| 	  *r++ = c; | ||||
| 	  break; | ||||
| 
 | ||||
| 	case CTLESC: case CTLNUL:		/* internal quoting characters */ | ||||
| 	  *r++ = CTLESC;			/* could be '\\'? */ | ||||
| 	  *r++ = c; | ||||
| 	  break; | ||||
| #endif | ||||
| 
 | ||||
| 	case '#':				/* comment char */ | ||||
| 	  if (s == string) | ||||
| 	    *r++ = '\\'; | ||||
| 	  /* FALLTHROUGH */ | ||||
| 	default: | ||||
| 	  *r++ = c; | ||||
| 	  break; | ||||
| 	} | ||||
|       if (backslash_table[c] == 1) | ||||
| 	*r++ = '\\'; | ||||
|       else if (c == '#' && s == string)			/* comment char */ | ||||
| 	*r++ = '\\'; | ||||
|       else if ((flags&1) && c == '~' && (s == string || s[-1] == ':' || s[-1] == '=')) | ||||
|         /* Tildes are special at the start of a word or after a `:' or `='
 | ||||
| 	   (technically unquoted, but it doesn't make a difference in practice) */ | ||||
| 	*r++ = '\\'; | ||||
|       *r++ = c; | ||||
|     } | ||||
| 
 | ||||
|   *r = '\0'; | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ | |||
|    Unix snprintf implementation. | ||||
|    derived from inetutils/libinetutils/snprintf.c Version 1.1 | ||||
| 
 | ||||
|    Copyright (C) 2001,2006,2010 Free Software Foundation, Inc. | ||||
|    Copyright (C) 2001,2006,2010,2012 Free Software Foundation, Inc. | ||||
| 
 | ||||
|    This file is part of GNU Bash, the Bourne Again SHell. | ||||
| 
 | ||||
|  | @ -26,7 +26,7 @@ | |||
|    You should have received a copy of the GNU General Public License | ||||
|    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 | ||||
|     | ||||
|    Revision History: | ||||
|    Original (pre-bash) Revision History: | ||||
| 
 | ||||
|    1.1: | ||||
|       *  added changes from Miles Bader | ||||
|  | @ -50,7 +50,6 @@ | |||
|  * Currently doesn't handle (and bash/readline doesn't use): | ||||
|  *	* *M$ width, precision specifications | ||||
|  *	* %N$ numbered argument conversions | ||||
|  *	* inf, nan floating values imperfect (if isinf(), isnan() not in libc) | ||||
|  *	* support for `F' is imperfect with ldfallback(), since underlying | ||||
|  *	  printf may not handle it -- should ideally have another autoconf test | ||||
|  */ | ||||
|  | @ -303,11 +302,30 @@ static void dfallback __P((struct DATA *, const char *, const char *, double)); | |||
| 
 | ||||
| static char *groupnum __P((char *)); | ||||
| 
 | ||||
| #ifndef HAVE_ISINF_IN_LIBC | ||||
| static int isinf __P((double)); | ||||
| #if defined (HAVE_LONG_DOUBLE) | ||||
| #  define LONGDOUBLE long double | ||||
| #else | ||||
| #  define LONGDOUBLE double | ||||
| #endif | ||||
| #ifndef HAVE_ISNAN_IN_LIBC | ||||
| static int isnan __P((double)); | ||||
| 
 | ||||
| #ifndef isnan | ||||
|   static inline int isnan_f  (float       x) { return x != x; } | ||||
|   static inline int isnan_d  (double      x) { return x != x; } | ||||
|   static inline int isnan_ld (LONGDOUBLE  x) { return x != x; } | ||||
|   # define isnan(x) \ | ||||
|       (sizeof (x) == sizeof (LONGDOUBLE) ? isnan_ld (x) \ | ||||
|        : sizeof (x) == sizeof (double) ? isnan_d (x) \ | ||||
|        : isnan_f (x)) | ||||
| #endif | ||||
|    | ||||
| #ifndef isinf | ||||
|   static inline int isinf_f  (float       x) { return !isnan (x) && isnan (x - x); } | ||||
|   static inline int isinf_d  (double      x) { return !isnan (x) && isnan (x - x); } | ||||
|   static inline int isinf_ld (LONGDOUBLE  x) { return !isnan (x) && isnan (x - x); } | ||||
|   # define isinf(x) \ | ||||
|       (sizeof (x) == sizeof (LONGDOUBLE) ? isinf_ld (x) \ | ||||
|        : sizeof (x) == sizeof (double) ? isinf_d (x) \ | ||||
|        : isinf_f (x)) | ||||
| #endif | ||||
| 
 | ||||
| #ifdef DRIVER | ||||
|  | @ -371,7 +389,7 @@ static void xfree __P((void *)); | |||
| 	while (0) | ||||
| 
 | ||||
| #define PUT_PLUS(d, p, zero) \ | ||||
| 	    if ((d) > zero && (p)->justify == RIGHT) \ | ||||
| 	    if (((p)->flags & PF_PLUS) && (d) > zero) \ | ||||
| 	      PUT_CHAR('+', p) | ||||
| 
 | ||||
| #define PUT_SPACE(d, p, zero) \ | ||||
|  | @ -431,9 +449,9 @@ static void xfree __P((void *)); | |||
| 	  if (lv) \ | ||||
| 	    { \ | ||||
| 	      if (lv->decimal_point && lv->decimal_point[0]) \ | ||||
| 	        (d) = lv->decimal_point[0]; \ | ||||
| 		(d) = lv->decimal_point[0]; \ | ||||
| 	      if (lv->thousands_sep && lv->thousands_sep[0]) \ | ||||
| 	        (t) = lv->thousands_sep[0]; \ | ||||
| 		(t) = lv->thousands_sep[0]; \ | ||||
| 	      (g) = lv->grouping ? lv->grouping : ""; \ | ||||
| 	      if (*(g) == '\0' || *(g) == CHAR_MAX || (t) == -1) (g) = 0; \ | ||||
| 	    } \ | ||||
|  | @ -574,7 +592,7 @@ integral(real, ip) | |||
| /* 
 | ||||
|  * return an ascii representation of the integral part of the number | ||||
|  * and set fract to be an ascii representation of the fraction part | ||||
|  * the container for the fraction and the integral part or staticly | ||||
|  * the container for the fraction and the integral part or statically | ||||
|  * declare with fix size  | ||||
|  */ | ||||
| static char * | ||||
|  | @ -586,10 +604,9 @@ numtoa(number, base, precision, fract) | |||
|   register int i, j; | ||||
|   double ip, fp; /* integer and fraction part */ | ||||
|   double fraction; | ||||
|   int digits = MAX_INT - 1; | ||||
|   int digits, sign; | ||||
|   static char integral_part[MAX_INT]; | ||||
|   static char fraction_part[MAX_FRACT]; | ||||
|   double sign; | ||||
|   int ch; | ||||
| 
 | ||||
|   /* taking care of the obvious case: 0.0 */ | ||||
|  | @ -607,8 +624,12 @@ numtoa(number, base, precision, fract) | |||
|       return integral_part; | ||||
|     } | ||||
| 
 | ||||
|   /* -0 is tricky */ | ||||
|   sign = (number == -0.) ? '-' : ((number < 0.) ? '-' : '+'); | ||||
|   digits = MAX_INT - 1; | ||||
| 
 | ||||
|   /* for negative numbers */ | ||||
|   if ((sign = number) < 0.) | ||||
|   if (sign == '-') | ||||
|     { | ||||
|       number = -number; | ||||
|       digits--; /* sign consume one digit */ | ||||
|  | @ -643,7 +664,7 @@ numtoa(number, base, precision, fract) | |||
|       integral_part[i] = '9'; | ||||
| 
 | ||||
|   /* put the sign ? */ | ||||
|   if (sign < 0.) | ||||
|   if (sign == '-') | ||||
|     integral_part[i++] = '-'; | ||||
| 
 | ||||
|   integral_part[i] = '\0'; | ||||
|  | @ -682,9 +703,13 @@ number(p, d, base) | |||
|   long sd; | ||||
|   int flags; | ||||
| 
 | ||||
|   /* An explicit precision turns off the zero-padding flag. */ | ||||
|   /* An explicit precision turns off the zero-padding flag and sets the
 | ||||
|      pad character back to space. */ | ||||
|   if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT)) | ||||
|     p->flags &= ~PF_ZEROPAD; | ||||
|     { | ||||
|       p->flags &= ~PF_ZEROPAD; | ||||
|       p->pad = ' '; | ||||
|     } | ||||
| 
 | ||||
|   sd = d;	/* signed for ' ' padding in base 10 */ | ||||
|   flags = 0; | ||||
|  | @ -698,10 +723,11 @@ number(p, d, base) | |||
|     { | ||||
|       GETLOCALEDATA(decpoint, thoussep, grouping); | ||||
|       if (grouping && (t = groupnum (tmp))) | ||||
|         tmp = t; | ||||
| 	tmp = t; | ||||
|     } | ||||
| 
 | ||||
|   p->width -= strlen(tmp); | ||||
|   /* need to add one for any `+', but we only add one in base 10 */ | ||||
|   p->width -= strlen(tmp) + (base == 10 && d > 0 && (p->flags & PF_PLUS)); | ||||
|   PAD_RIGHT(p); | ||||
| 
 | ||||
|   if ((p->flags & PF_DOT) && p->precision > 0) | ||||
|  | @ -753,9 +779,13 @@ lnumber(p, d, base) | |||
|   long long sd; | ||||
|   int flags; | ||||
| 
 | ||||
|   /* An explicit precision turns off the zero-padding flag. */ | ||||
|   /* An explicit precision turns off the zero-padding flag and sets the
 | ||||
|      pad character back to space. */ | ||||
|   if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT)) | ||||
|     p->flags &= ~PF_ZEROPAD; | ||||
|     { | ||||
|       p->flags &= ~PF_ZEROPAD; | ||||
|       p->pad = ' '; | ||||
|     } | ||||
| 
 | ||||
|   sd = d;	/* signed for ' ' padding in base 10 */ | ||||
|   flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0; | ||||
|  | @ -768,10 +798,11 @@ lnumber(p, d, base) | |||
|     { | ||||
|       GETLOCALEDATA(decpoint, thoussep, grouping); | ||||
|       if (grouping && (t = groupnum (tmp))) | ||||
|         tmp = t; | ||||
| 	tmp = t; | ||||
|     } | ||||
| 
 | ||||
|   p->width -= strlen(tmp); | ||||
|   /* need to add one for any `+', but we only add one in base 10 */ | ||||
|   p->width -= strlen(tmp) + (base == 10 && d > 0 && (p->flags & PF_PLUS)); | ||||
|   PAD_RIGHT(p); | ||||
| 
 | ||||
|   if ((p->flags & PF_DOT) && p->precision > 0) | ||||
|  | @ -875,11 +906,11 @@ wstrings(p, tmp) | |||
|     { | ||||
|       len = wcsrtombs (NULL, &ws, 0, &mbs); | ||||
|       if (len != (size_t)-1) | ||||
|         { | ||||
| 	{ | ||||
| 	  memset (&mbs, '\0', sizeof (mbstate_t)); | ||||
| 	  os = (char *)xmalloc (len + 1); | ||||
| 	  (void)wcsrtombs (os, &ws, len + 1, &mbs); | ||||
|         } | ||||
| 	} | ||||
|     } | ||||
|   if (len == (size_t)-1) | ||||
|     { | ||||
|  | @ -919,32 +950,6 @@ wchars (p, wc) | |||
| 
 | ||||
| #ifdef FLOATING_POINT | ||||
| 
 | ||||
| #ifndef HAVE_ISINF_IN_LIBC | ||||
| /* Half-assed versions, since we don't want to link with libm. */ | ||||
| static int | ||||
| isinf(d) | ||||
|      double d; | ||||
| { | ||||
| #ifdef DBL_MAX | ||||
|   if (d < DBL_MIN) | ||||
|     return -1; | ||||
|   else if (d > DBL_MAX) | ||||
|     return 1; | ||||
|   else | ||||
| #endif | ||||
|     return 0; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #ifndef HAVE_ISNAN_IN_LIBC | ||||
| static int | ||||
| isnan(d) | ||||
|      double d; | ||||
| { | ||||
|   return 0; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /* Check for [+-]infinity and NaN.  If MODE == 1, we check for Infinity, else
 | ||||
|    (mode == 2) we check for NaN.  This does the necessary printing.  Returns | ||||
|    1 if Inf or Nan, 0 if not. */ | ||||
|  | @ -1002,19 +1007,35 @@ floating(p, d) | |||
|     { | ||||
|       /* smash the trailing zeros unless altform */ | ||||
|       for (i = strlen(tmp2) - 1; i >= 0 && tmp2[i] == '0'; i--) | ||||
|         tmp2[i] = '\0';  | ||||
| 	tmp2[i] = '\0';  | ||||
|       if (tmp2[0] == '\0') | ||||
| 	p->precision = 0; | ||||
|     } | ||||
| 
 | ||||
|   /* calculate the padding. 1 for the dot */ | ||||
|   p->width = p->width - | ||||
|   	    /* XXX - should this be d>0. && (p->flags & PF_PLUS) ? */ | ||||
| #if 0 | ||||
| 	    ((d > 0. && p->justify == RIGHT) ? 1:0) - | ||||
| #else | ||||
| 	    ((d > 0. && (p->flags & PF_PLUS)) ? 1:0) - | ||||
| #endif | ||||
| 	    ((p->flags & PF_SPACE) ? 1:0) - | ||||
| 	    strlen(tmp) - p->precision - | ||||
| 	    ((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0);	/* radix char */ | ||||
|   PAD_RIGHT(p);   | ||||
|   PUT_PLUS(d, p, 0.); | ||||
| 
 | ||||
|   if (p->pad == ' ') | ||||
|     { | ||||
|       PAD_RIGHT(p); | ||||
|       PUT_PLUS(d, p, 0.); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (*tmp == '-') | ||||
| 	PUT_CHAR(*tmp++, p); | ||||
|       PUT_PLUS(d, p, 0.); | ||||
|       PAD_RIGHT(p); | ||||
|     } | ||||
|   PUT_SPACE(d, p, 0.); | ||||
| 
 | ||||
|   while (*tmp) | ||||
|  | @ -1058,14 +1079,30 @@ exponent(p, d) | |||
|   tmp = dtoa(d, p->precision, &tmp2); | ||||
| 
 | ||||
|   /* 1 for unit, 1 for the '.', 1 for 'e|E',
 | ||||
|    * 1 for '+|-', 2 for 'exp' */ | ||||
|    * 1 for '+|-', 2 for 'exp'  (but no `.' if precision == 0 */ | ||||
|   /* calculate how much padding need */ | ||||
|   p->width = p->width -  | ||||
|   	    /* XXX - should this be d>0. && (p->flags & PF_PLUS) ? */ | ||||
| #if 0 | ||||
| 	     ((d > 0. && p->justify == RIGHT) ? 1:0) - | ||||
| 	     ((p->flags & PF_SPACE) ? 1:0) - p->precision - 6; | ||||
| #else | ||||
| 	     ((d > 0. && (p->flags & PF_PLUS)) ? 1:0) - | ||||
| #endif | ||||
| 	     (p->precision != 0 || (p->flags & PF_ALTFORM)) - | ||||
| 	     ((p->flags & PF_SPACE) ? 1:0) - p->precision - 5; | ||||
| 
 | ||||
|   PAD_RIGHT(p); | ||||
|   PUT_PLUS(d, p, 0.); | ||||
|   if (p->pad == ' ') | ||||
|     { | ||||
|       PAD_RIGHT(p); | ||||
|       PUT_PLUS(d, p, 0.); | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       if (*tmp == '-') | ||||
| 	PUT_CHAR(*tmp++, p); | ||||
|       PUT_PLUS(d, p, 0.); | ||||
|       PAD_RIGHT(p); | ||||
|     } | ||||
|   PUT_SPACE(d, p, 0.); | ||||
| 
 | ||||
|   while (*tmp) | ||||
|  | @ -1163,7 +1200,7 @@ groupnum (s) | |||
| 	  else if (*g == CHAR_MAX) | ||||
| 	    { | ||||
| 	      do | ||||
| 	        *--re = *--se; | ||||
| 		*--re = *--se; | ||||
| 	      while (se > s); | ||||
| 	      break; | ||||
| 	    } | ||||
|  | @ -1295,10 +1332,6 @@ vsnprintf_internal(data, string, length, format, args) | |||
| 	      case '#': | ||||
| 		data->flags |= PF_ALTFORM; | ||||
| 		continue; | ||||
| 	      case '0': | ||||
| 		data->flags |= PF_ZEROPAD; | ||||
| 		data->pad = '0'; | ||||
| 		continue; | ||||
| 	      case '*': | ||||
| 		if (data->flags & PF_DOT) | ||||
| 		  data->flags |= PF_STAR_P; | ||||
|  | @ -1322,13 +1355,25 @@ vsnprintf_internal(data, string, length, format, args) | |||
| 		if ((data->flags & PF_DOT) == 0) | ||||
| 		  { | ||||
| 		    data->flags |= PF_PLUS; | ||||
| 		    data->justify = RIGHT; | ||||
| 		    if ((data->flags & PF_LADJUST) == 0) | ||||
| 		      data->justify = RIGHT; | ||||
| 		  } | ||||
| 		continue; | ||||
| 	      case '\'': | ||||
| 		data->flags |= PF_THOUSANDS; | ||||
| 		continue; | ||||
| 
 | ||||
| 	      case '0': | ||||
| 		/* If we're not specifying precision (in which case we've seen
 | ||||
| 		   a `.') and we're not performing left-adjustment (in which | ||||
| 		   case the `0' is ignored), a `0' is taken as the zero-padding | ||||
| 		   flag. */ | ||||
| 	        if ((data->flags & (PF_DOT|PF_LADJUST)) == 0) | ||||
| 		  { | ||||
| 		    data->flags |= PF_ZEROPAD; | ||||
| 		    data->pad = '0'; | ||||
| 		    continue; | ||||
| 		  } | ||||
| 	      case '1': case '2': case '3': | ||||
| 	      case '4': case '5': case '6': | ||||
| 	      case '7': case '8': case '9': | ||||
|  | @ -1410,8 +1455,9 @@ conv_break: | |||
| 		else | ||||
| 		  { | ||||
| 		    /* reduce precision by 1 because of leading digit before
 | ||||
| 		       decimal point in e format. */ | ||||
| 		    data->precision--; | ||||
| 		       decimal point in e format, unless specified as 0. */ | ||||
| 		    if (data->precision > 0) | ||||
| 		      data->precision--; | ||||
| 		    exponent(data, d); | ||||
| 		  } | ||||
| 		state = 0; | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ | |||
| #include <bashtypes.h> | ||||
| #include <posixdir.h> | ||||
| #include <posixstat.h> | ||||
| #ifndef _MINIX | ||||
| #if defined (HAVE_SYS_PARAM_H) | ||||
| #include <sys/param.h> | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| /* Searching in a string.
 | ||||
|    Copyright (C) 2003, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. | ||||
|    Copyright (C) 2012 Free Software Foundation, Inc. | ||||
| 
 | ||||
|    This program is free software: you can redistribute it and/or modify | ||||
|    it under the terms of the GNU General Public License as published by | ||||
|  | @ -15,130 +15,21 @@ | |||
|    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 | ||||
| 
 | ||||
| #include <config.h> | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| /* Specification.  */ | ||||
| #include <string.h> | ||||
| 
 | ||||
|   /* On 32-bit hardware, choosing longword to be a 32-bit unsigned
 | ||||
|      long instead of a 64-bit uintmax_t tends to give better | ||||
|      performance.  On 64-bit hardware, unsigned long is generally 64 | ||||
|      bits already.  Change this typedef to experiment with | ||||
|      performance.  */ | ||||
|   typedef unsigned long int longword; | ||||
| 
 | ||||
| /* Find the first occurrence of C in S or the final NUL byte.  */ | ||||
| char * | ||||
| strchrnul (s, c_in) | ||||
|      const char *s; | ||||
|      int c_in; | ||||
| { | ||||
|   const unsigned char *char_ptr; | ||||
|   const longword *longword_ptr; | ||||
|   longword repeated_one; | ||||
|   longword repeated_c; | ||||
|   unsigned char c; | ||||
|   char c; | ||||
|   register char *s1; | ||||
| 
 | ||||
|   c = (unsigned char) c_in; | ||||
|   if (c == 0)		/* find final null byte */ | ||||
|     return (char *)(s ? (s + strlen (s)) : s); | ||||
| 
 | ||||
|   /* Handle the first few bytes by reading one byte at a time.
 | ||||
|      Do this until CHAR_PTR is aligned on a longword boundary.  */ | ||||
|   for (char_ptr = (const unsigned char *) s; | ||||
|        (size_t) char_ptr % sizeof (longword) != 0; | ||||
|        ++char_ptr) | ||||
|     if (!*char_ptr || *char_ptr == c) | ||||
|       return (char *) char_ptr; | ||||
| 
 | ||||
|   longword_ptr = (const longword *) char_ptr; | ||||
| 
 | ||||
|   /* All these elucidatory comments refer to 4-byte longwords,
 | ||||
|      but the theory applies equally well to any size longwords.  */ | ||||
| 
 | ||||
|   /* Compute auxiliary longword values:
 | ||||
|      repeated_one is a value which has a 1 in every byte. | ||||
|      repeated_c has c in every byte.  */ | ||||
|   repeated_one = 0x01010101; | ||||
|   repeated_c = c | (c << 8); | ||||
|   repeated_c |= repeated_c << 16; | ||||
|   if (0xffffffffU < (longword) -1) | ||||
|     { | ||||
|       repeated_one |= repeated_one << 31 << 1; | ||||
|       repeated_c |= repeated_c << 31 << 1; | ||||
|       if (8 < sizeof (longword)) | ||||
|         { | ||||
|           size_t i; | ||||
| 
 | ||||
|           for (i = 64; i < sizeof (longword) * 8; i *= 2) | ||||
|             { | ||||
|               repeated_one |= repeated_one << i; | ||||
|               repeated_c |= repeated_c << i; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   /* Instead of the traditional loop which tests each byte, we will
 | ||||
|      test a longword at a time.  The tricky part is testing if *any of | ||||
|      the four* bytes in the longword in question are equal to NUL or | ||||
|      c.  We first use an xor with repeated_c.  This reduces the task | ||||
|      to testing whether *any of the four* bytes in longword1 or | ||||
|      longword2 is zero. | ||||
| 
 | ||||
|      Let's consider longword1.  We compute tmp = | ||||
|        ((longword1 - repeated_one) & ~longword1) & (repeated_one << 7). | ||||
|      That is, we perform the following operations: | ||||
|        1. Subtract repeated_one. | ||||
|        2. & ~longword1. | ||||
|        3. & a mask consisting of 0x80 in every byte. | ||||
|      Consider what happens in each byte: | ||||
|        - If a byte of longword1 is zero, step 1 and 2 transform it into 0xff, | ||||
|          and step 3 transforms it into 0x80.  A carry can also be propagated | ||||
|          to more significant bytes. | ||||
|        - If a byte of longword1 is nonzero, let its lowest 1 bit be at | ||||
|          position k (0 <= k <= 7); so the lowest k bits are 0.  After step 1, | ||||
|          the byte ends in a single bit of value 0 and k bits of value 1. | ||||
|          After step 2, the result is just k bits of value 1: 2^k - 1.  After | ||||
|          step 3, the result is 0.  And no carry is produced. | ||||
|      So, if longword1 has only non-zero bytes, tmp is zero. | ||||
|      Whereas if longword1 has a zero byte, call j the position of the least | ||||
|      significant zero byte.  Then the result has a zero at positions 0, ..., | ||||
|      j-1 and a 0x80 at position j.  We cannot predict the result at the more | ||||
|      significant bytes (positions j+1..3), but it does not matter since we | ||||
|      already have a non-zero bit at position 8*j+7. | ||||
| 
 | ||||
|      The test whether any byte in longword1 or longword2 is zero is equivalent | ||||
|      to testing whether tmp1 is nonzero or tmp2 is nonzero.  We can combine | ||||
|      this into a single test, whether (tmp1 | tmp2) is nonzero. | ||||
| 
 | ||||
|      This test can read more than one byte beyond the end of a string, | ||||
|      depending on where the terminating NUL is encountered.  However, | ||||
|      this is considered safe since the initialization phase ensured | ||||
|      that the read will be aligned, therefore, the read will not cross | ||||
|      page boundaries and will not cause a fault.  */ | ||||
| 
 | ||||
|   while (1) | ||||
|     { | ||||
|       longword longword1 = *longword_ptr ^ repeated_c; | ||||
|       longword longword2 = *longword_ptr; | ||||
| 
 | ||||
|       if (((((longword1 - repeated_one) & ~longword1) | ||||
|             | ((longword2 - repeated_one) & ~longword2)) | ||||
|            & (repeated_one << 7)) != 0) | ||||
|         break; | ||||
|       longword_ptr++; | ||||
|     } | ||||
| 
 | ||||
|   char_ptr = (const unsigned char *) longword_ptr; | ||||
| 
 | ||||
|   /* At this point, we know that one of the sizeof (longword) bytes
 | ||||
|      starting at char_ptr is == 0 or == c.  On little-endian machines, | ||||
|      we could determine the first such byte without any further memory | ||||
|      accesses, just by looking at the tmp result from the last loop | ||||
|      iteration.  But this does not work on big-endian machines. | ||||
|      Choose code that works in both cases.  */ | ||||
| 
 | ||||
|   char_ptr = (unsigned char *) longword_ptr; | ||||
|   while (*char_ptr && (*char_ptr != c)) | ||||
|     char_ptr++; | ||||
|   return (char *) char_ptr; | ||||
|   for (c = c_in, s1 = (char *)s; s1 && *s1 && *s1 != c; s1++) | ||||
|     ; | ||||
|   return (s1); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										42
									
								
								lib/sh/strdup.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								lib/sh/strdup.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,42 @@ | |||
| /* strdup - return a copy of a string in newly-allocated memory. */ | ||||
| 
 | ||||
| /* Copyright (C) 2013 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> | ||||
| 
 | ||||
| /* Get specification.  */ | ||||
| #include <string.h> | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
| /* Duplicate S, returning an identical malloc'd string.  */ | ||||
| char * | ||||
| strdup (s) | ||||
|      const char *s; | ||||
| { | ||||
|   size_t len; | ||||
|   void *new; | ||||
| 
 | ||||
|   len = strlen (s) + 1; | ||||
|   if ((new = malloc (len)) == NULL) | ||||
|     return NULL; | ||||
| 
 | ||||
|   memcpy (new, s, len); | ||||
|   return ((char *)new); | ||||
| } | ||||
|  | @ -23,7 +23,7 @@ | |||
| #if !defined (HAVE_STRERROR) | ||||
| 
 | ||||
| #include <bashtypes.h> | ||||
| #ifndef _MINIX | ||||
| #if defined (HAVE_SYS_PARAM_H) | ||||
| #  include <sys/param.h> | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -38,6 +38,7 @@ | |||
|  * Updated September, 2000 | ||||
|  * Updated December, 2001 | ||||
|  * Updated January, 2011 | ||||
|  * Updated April, 2012 | ||||
|  * | ||||
|  * Fixes from ado@elsie.nci.nih.gov, | ||||
|  * February 1991, May 1992 | ||||
|  | @ -75,6 +76,7 @@ | |||
| #define VMS_EXT		1	/* include %v for VMS date format */ | ||||
| #define HPUX_EXT	1	/* non-conflicting stuff in HP-UX date */ | ||||
| #define POSIX_SEMANTICS	1	/* call tzset() if TZ changes */ | ||||
| #define POSIX_2008	1	/* flag and fw for C, F, G, Y formats */ | ||||
| 
 | ||||
| #undef strchr	/* avoid AIX weirdness */ | ||||
| 
 | ||||
|  | @ -96,27 +98,25 @@ static int iso8601wknum(const struct tm *timeptr); | |||
| 
 | ||||
| #define range(low, item, hi)	max(low, min(item, hi)) | ||||
| 
 | ||||
| #if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME) | ||||
| /* Whew! This stuff is a mess. */ | ||||
| #if !defined(OS2) && !defined(MSDOS) && !defined(__CYGWIN__) && defined(HAVE_TZNAME) | ||||
| extern char *tzname[2]; | ||||
| extern int daylight; | ||||
| #if defined(SOLARIS) || defined(mips) || defined (M_UNIX) | ||||
| extern long int timezone, altzone; | ||||
| #else | ||||
| #  if defined (HPUX) | ||||
| #  if defined (HPUX) || defined(__hpux) | ||||
| extern long int timezone; | ||||
| #  else | ||||
| #    if !defined(__CYGWIN__) | ||||
| extern int timezone, altzone; | ||||
| #  endif /* !HPUX */ | ||||
| #endif /* !SOLARIS && !mips && !M_UNIX */ | ||||
| #    endif | ||||
| #  endif | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| #undef min	/* just in case */ | ||||
| 
 | ||||
| /* format for %+ -- currently unused */ | ||||
| #ifndef NATIONAL_FORMAT | ||||
| #define NATIONAL_FORMAT "%a %b %e %H:%M:%S %Z %Y" | ||||
| #endif | ||||
| 
 | ||||
| /* min --- return minimum of two numbers */ | ||||
| 
 | ||||
| static inline int | ||||
|  | @ -135,6 +135,34 @@ max(int a, int b) | |||
| 	return (a > b ? a : b); | ||||
| } | ||||
| 
 | ||||
| #ifdef POSIX_2008 | ||||
| /* iso_8601_2000_year --- format a year per ISO 8601:2000 as in 1003.1 */ | ||||
| 
 | ||||
| static void | ||||
| iso_8601_2000_year(char *buf, int year, size_t fw) | ||||
| { | ||||
| 	int extra; | ||||
| 	char sign = '\0'; | ||||
| 
 | ||||
| 	if (year >= -9999 && year <= 9999) { | ||||
| 		sprintf(buf, "%0*d", (int) fw, year); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* now things get weird */ | ||||
| 	if (year > 9999) { | ||||
| 		sign = '+'; | ||||
| 	} else { | ||||
| 		sign = '-'; | ||||
| 		year = -year; | ||||
| 	} | ||||
| 
 | ||||
| 	extra = year / 10000; | ||||
| 	year %= 10000; | ||||
| 	sprintf(buf, "%c_%04d_%d", sign, extra, year); | ||||
| } | ||||
| #endif /* POSIX_2008 */ | ||||
| 
 | ||||
| /* strftime --- produce formatted time */ | ||||
| 
 | ||||
| size_t | ||||
|  | @ -155,12 +183,19 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) | |||
| #ifndef HAVE_TM_ZONE | ||||
| #ifndef HAVE_TM_NAME | ||||
| #ifndef HAVE_TZNAME | ||||
| #ifndef __CYGWIN__ | ||||
| 	extern char *timezone(); | ||||
| 	struct timeval tv; | ||||
| 	struct timezone zone; | ||||
| #endif /* __CYGWIN__ */ | ||||
| #endif /* HAVE_TZNAME */ | ||||
| #endif /* HAVE_TM_NAME */ | ||||
| #endif /* HAVE_TM_ZONE */ | ||||
| #ifdef POSIX_2008 | ||||
| 	int pad; | ||||
| 	size_t fw; | ||||
| 	char flag; | ||||
| #endif /* POSIX_2008 */ | ||||
| 
 | ||||
| 	/* various tables, useful in North America */ | ||||
| 	static const char *days_a[] = { | ||||
|  | @ -234,6 +269,40 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) | |||
| 			*s++ = *format; | ||||
| 			continue; | ||||
| 		} | ||||
| #ifdef POSIX_2008 | ||||
| 		pad = '\0'; | ||||
| 		fw = 0; | ||||
| 		flag = '\0'; | ||||
| 		switch (*++format) { | ||||
| 		case '+': | ||||
| 			flag = '+'; | ||||
| 			/* fall through */ | ||||
| 		case '0': | ||||
| 			pad = '0'; | ||||
| 			format++; | ||||
| 			break; | ||||
| 
 | ||||
| 		case '1': | ||||
| 		case '2': | ||||
| 		case '3': | ||||
| 		case '4': | ||||
| 		case '5': | ||||
| 		case '6': | ||||
| 		case '7': | ||||
| 		case '8': | ||||
| 		case '9': | ||||
| 			break; | ||||
| 
 | ||||
| 		default: | ||||
| 			format--; | ||||
| 			goto again; | ||||
| 		} | ||||
| 		for (; isdigit(*format); format++) { | ||||
| 			fw = fw * 10 + (*format - '0'); | ||||
| 		} | ||||
| 		format--; | ||||
| #endif /* POSIX_2008 */ | ||||
| 
 | ||||
| 	again: | ||||
| 		switch (*++format) { | ||||
| 		case '\0': | ||||
|  | @ -285,8 +354,19 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) | |||
| 			break; | ||||
| 
 | ||||
| 		case 'C': | ||||
| #ifdef POSIX_2008 | ||||
| 			if (pad != '\0' && fw > 0) { | ||||
| 				size_t min_fw = (flag ? 3 : 2); | ||||
| 
 | ||||
| 				fw = max(fw, min_fw); | ||||
| 				sprintf(tbuf, flag | ||||
| 						? "%+0*ld" | ||||
| 						: "%0*ld", (int) fw, | ||||
| 						(timeptr->tm_year + 1900L) / 100); | ||||
| 			} else | ||||
| #endif /* POSIX_2008 */ | ||||
| 		century: | ||||
| 			sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100); | ||||
| 				sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100); | ||||
| 			break; | ||||
| 
 | ||||
| 		case 'd':	/* day of the month, 01 - 31 */ | ||||
|  | @ -307,7 +387,30 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) | |||
| 			goto again; | ||||
| 
 | ||||
| 		case 'F':	/* ISO 8601 date representation */ | ||||
| 		{ | ||||
| #ifdef POSIX_2008 | ||||
| 			/*
 | ||||
| 			 * Field width for %F is for the whole thing. | ||||
| 			 * It must be at least 10. | ||||
| 			 */ | ||||
| 			char m_d[10]; | ||||
| 			strftime(m_d, sizeof m_d, "-%m-%d", timeptr); | ||||
| 			size_t min_fw = 10; | ||||
| 
 | ||||
| 			if (pad != '\0' && fw > 0) { | ||||
| 				fw = max(fw, min_fw); | ||||
| 			} else { | ||||
| 				fw = min_fw; | ||||
| 			} | ||||
| 
 | ||||
| 			fw -= 6;	/* -XX-XX at end are invariant */ | ||||
| 
 | ||||
| 			iso_8601_2000_year(tbuf, timeptr->tm_year + 1900, fw); | ||||
| 			strcat(tbuf, m_d); | ||||
| #else | ||||
| 			strftime(tbuf, sizeof tbuf, "%Y-%m-%d", timeptr); | ||||
| #endif /* POSIX_2008 */ | ||||
| 		} | ||||
| 			break; | ||||
| 
 | ||||
| 		case 'g': | ||||
|  | @ -329,8 +432,20 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) | |||
| 			else | ||||
| 				y = 1900L + timeptr->tm_year; | ||||
| 
 | ||||
| 			if (*format == 'G') | ||||
| 				sprintf(tbuf, "%ld", y); | ||||
| 			if (*format == 'G') { | ||||
| #ifdef POSIX_2008 | ||||
| 				if (pad != '\0' && fw > 0) { | ||||
| 					size_t min_fw = 4; | ||||
| 
 | ||||
| 					fw = max(fw, min_fw); | ||||
| 					sprintf(tbuf, flag | ||||
| 							? "%+0*ld" | ||||
| 							: "%0*ld", (int) fw, | ||||
| 							y); | ||||
| 				} else | ||||
| #endif /* POSIX_2008 */ | ||||
| 					sprintf(tbuf, "%ld", y); | ||||
| 			} | ||||
| 			else | ||||
| 				sprintf(tbuf, "%02ld", y % 100); | ||||
| 			break; | ||||
|  | @ -455,7 +570,17 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) | |||
| 			break; | ||||
| 
 | ||||
| 		case 'Y':	/* year with century */ | ||||
| 		fullyear: | ||||
| #ifdef POSIX_2008 | ||||
| 			if (pad != '\0' && fw > 0) { | ||||
| 				size_t min_fw = 4; | ||||
| 
 | ||||
| 				fw = max(fw, min_fw); | ||||
| 				sprintf(tbuf, flag | ||||
| 						? "%+0*ld" | ||||
| 						: "%0*ld", (int) fw, | ||||
| 						1900L + timeptr->tm_year); | ||||
| 			} else | ||||
| #endif /* POSIX_2008 */ | ||||
| 			sprintf(tbuf, "%ld", 1900L + timeptr->tm_year); | ||||
| 			break; | ||||
| 
 | ||||
|  | @ -496,12 +621,12 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr) | |||
| 			 * Systems with tzname[] probably have timezone as | ||||
| 			 * secs west of GMT.  Convert to mins east of GMT. | ||||
| 			 */ | ||||
| #  ifdef HPUX | ||||
| #  if defined(__hpux) || defined (HPUX) || defined(__CYGWIN__) | ||||
| 			off = -timezone / 60; | ||||
| #  else | ||||
| 			/* ADR: 4 August 2001, fixed this per gazelle@interaccess.com */ | ||||
| 			off = -(daylight ? altzone : timezone) / 60; | ||||
| #  endif /* !HPUX */ | ||||
| #  endif | ||||
| #else /* !HAVE_TZNAME */ | ||||
| 			gettimeofday(& tv, & zone); | ||||
| 			off = -zone.tz_minuteswest; | ||||
|  |  | |||
|  | @ -40,6 +40,14 @@ strvec_create (n) | |||
|   return ((char **)xmalloc ((n) * sizeof (char *))); | ||||
| } | ||||
| 
 | ||||
| /* Allocate an array of strings with room for N members. */ | ||||
| char ** | ||||
| strvec_mcreate (n) | ||||
|      int n; | ||||
| { | ||||
|   return ((char **)malloc ((n) * sizeof (char *))); | ||||
| } | ||||
| 
 | ||||
| char ** | ||||
| strvec_resize (array, nsize) | ||||
|      char **array; | ||||
|  | @ -48,6 +56,14 @@ strvec_resize (array, nsize) | |||
|   return ((char **)xrealloc (array, nsize * sizeof (char *))); | ||||
| } | ||||
| 
 | ||||
| char ** | ||||
| strvec_mresize (array, nsize) | ||||
|      char **array; | ||||
|      int nsize; | ||||
| { | ||||
|   return ((char **)realloc (array, nsize * sizeof (char *))); | ||||
| } | ||||
| 
 | ||||
| /* Return the length of ARRAY, a NULL terminated array of char *. */ | ||||
| int | ||||
| strvec_len (array) | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ | |||
| 
 | ||||
| #include <stdc.h> | ||||
| 
 | ||||
| /* Find the first ocurrence in S of any character in ACCEPT.  */ | ||||
| /* Find the first occurrence in S of any character in ACCEPT.  */ | ||||
| char * | ||||
| strpbrk (s, accept) | ||||
|      register const char *s; | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /* strtrans.c - Translate and untranslate strings with ANSI-C escape sequences. */ | ||||
| 
 | ||||
| /* Copyright (C) 2000-2010 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 2000-2011 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of GNU Bash, the Bourne Again SHell. | ||||
| 
 | ||||
|  | @ -30,6 +30,9 @@ | |||
| 
 | ||||
| #include "shell.h" | ||||
| 
 | ||||
| #include "shmbchar.h" | ||||
| #include "shmbutil.h" | ||||
| 
 | ||||
| #ifdef ESC | ||||
| #undef ESC | ||||
| #endif | ||||
|  | @ -74,7 +77,7 @@ ansicstr (string, len, flags, sawc, rlen) | |||
| 	    case 'a': c = '\a'; break; | ||||
| 	    case 'v': c = '\v'; break; | ||||
| #else | ||||
| 	    case 'a': c = '\007'; break; | ||||
| 	    case 'a': c = (int) 0x07; break; | ||||
| 	    case 'v': c = (int) 0x0B; break; | ||||
| #endif | ||||
| 	    case 'b': c = '\b'; break; | ||||
|  | @ -144,7 +147,7 @@ ansicstr (string, len, flags, sawc, rlen) | |||
| 		  *r++ = '\\';	/* c remains unchanged */ | ||||
| 		  break; | ||||
| 		} | ||||
| 	      else if (v <= UCHAR_MAX) | ||||
| 	      else if (v <= 0x7f)	/* <= 0x7f translates directly */ | ||||
| 		{ | ||||
| 		  c = v; | ||||
| 		  break; | ||||
|  | @ -208,6 +211,11 @@ ansic_quote (str, flags, rlen) | |||
|   char *r, *ret, *s; | ||||
|   int l, rsize; | ||||
|   unsigned char c; | ||||
|   size_t clen; | ||||
|   int b; | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|   wchar_t wc; | ||||
| #endif | ||||
| 
 | ||||
|   if (str == 0 || *str == 0) | ||||
|     return ((char *)0); | ||||
|  | @ -219,10 +227,13 @@ ansic_quote (str, flags, rlen) | |||
|   *r++ = '$'; | ||||
|   *r++ = '\''; | ||||
| 
 | ||||
|   for (s = str, l = 0; *s; s++) | ||||
|   s = str; | ||||
| 
 | ||||
|   for (s = str; c = *s; s++) | ||||
|     { | ||||
|       c = *s; | ||||
|       l = 1;		/* 1 == add backslash; 0 == no backslash */ | ||||
|       b = l = 1;		/* 1 == add backslash; 0 == no backslash */ | ||||
|       clen = 1; | ||||
| 
 | ||||
|       switch (c) | ||||
| 	{ | ||||
| 	case ESC: c = 'E'; break; | ||||
|  | @ -230,7 +241,7 @@ ansic_quote (str, flags, rlen) | |||
| 	case '\a': c = 'a'; break; | ||||
| 	case '\v': c = 'v'; break; | ||||
| #else | ||||
| 	case '\007': c = 'a'; break; | ||||
| 	case 0x07: c = 'a'; break; | ||||
| 	case 0x0b: c = 'v'; break; | ||||
| #endif | ||||
| 
 | ||||
|  | @ -243,7 +254,14 @@ ansic_quote (str, flags, rlen) | |||
| 	case '\'': | ||||
| 	  break; | ||||
| 	default: | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
| 	  b = is_basic (c); | ||||
| 	  /* XXX - clen comparison to 0 is dicey */ | ||||
| 	  if ((b == 0 && ((clen = mbrtowc (&wc, s, MB_CUR_MAX, 0)) < 0 || MB_INVALIDCH (clen) || iswprint (wc) == 0)) || | ||||
| 	      (b == 1 && ISPRINT (c) == 0)) | ||||
| #else | ||||
| 	  if (ISPRINT (c) == 0) | ||||
| #endif | ||||
| 	    { | ||||
| 	      *r++ = '\\'; | ||||
| 	      *r++ = TOCHAR ((c >> 6) & 07); | ||||
|  | @ -254,9 +272,20 @@ ansic_quote (str, flags, rlen) | |||
| 	  l = 0; | ||||
| 	  break; | ||||
| 	} | ||||
|       if (b == 0 && clen == 0) | ||||
| 	break; | ||||
| 
 | ||||
|       if (l) | ||||
| 	*r++ = '\\'; | ||||
|       *r++ = c; | ||||
| 
 | ||||
|       if (clen == 1) | ||||
| 	*r++ = c; | ||||
|       else | ||||
| 	{ | ||||
| 	  for (b = 0; b < (int)clen; b++) | ||||
| 	    *r++ = (unsigned char)s[b]; | ||||
| 	  s += clen - 1;	/* -1 because of the increment above */ | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
|   *r++ = '\''; | ||||
|  | @ -266,6 +295,37 @@ ansic_quote (str, flags, rlen) | |||
|   return ret; | ||||
| } | ||||
| 
 | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
| int | ||||
| ansic_wshouldquote (string) | ||||
|      const char *string; | ||||
| { | ||||
|   const wchar_t *wcs; | ||||
|   wchar_t wcc; | ||||
| 
 | ||||
|   wchar_t *wcstr = NULL; | ||||
|   size_t slen; | ||||
| 
 | ||||
| 
 | ||||
|   slen = mbstowcs (wcstr, string, 0); | ||||
| 
 | ||||
|   if (slen == -1) | ||||
|     slen = 0; | ||||
|   wcstr = (wchar_t *)xmalloc (sizeof (wchar_t) * (slen + 1)); | ||||
|   mbstowcs (wcstr, string, slen + 1); | ||||
| 
 | ||||
|   for (wcs = wcstr; wcc = *wcs; wcs++) | ||||
|     if (iswprint(wcc) == 0) | ||||
|       { | ||||
| 	free (wcstr); | ||||
| 	return 1; | ||||
|       } | ||||
| 
 | ||||
|   free (wcstr); | ||||
|   return 0; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /* return 1 if we need to quote with $'...' because of non-printing chars. */ | ||||
| int | ||||
| ansic_shouldquote (string) | ||||
|  | @ -278,8 +338,14 @@ ansic_shouldquote (string) | |||
|     return 0; | ||||
| 
 | ||||
|   for (s = string; c = *s; s++) | ||||
|     if (ISPRINT (c) == 0) | ||||
|       return 1; | ||||
|     { | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
|       if (is_basic (c) == 0) | ||||
| 	return (ansic_wshouldquote (s)); | ||||
| #endif | ||||
|       if (ISPRINT (c) == 0) | ||||
| 	return 1; | ||||
|     } | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -31,6 +31,8 @@ | |||
| #  include <unistd.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <bashansi.h> | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| #include <errno.h> | ||||
| 
 | ||||
|  | @ -135,7 +137,7 @@ sh_mktmpname (nameroot, flags) | |||
|       filenum = (filenum << 1) ^ | ||||
| 		(unsigned long) time ((time_t *)0) ^ | ||||
| 		(unsigned long) dollar_dollar_pid ^ | ||||
| 		(unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++); | ||||
| 		(unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); | ||||
|       sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); | ||||
|       if (tmpnamelen > 0 && tmpnamelen < 32) | ||||
| 	filename[tdlen + 1 + tmpnamelen] = '\0'; | ||||
|  | @ -184,7 +186,7 @@ sh_mktmpfd (nameroot, flags, namep) | |||
|       filenum = (filenum << 1) ^ | ||||
| 		(unsigned long) time ((time_t *)0) ^ | ||||
| 		(unsigned long) dollar_dollar_pid ^ | ||||
| 		(unsigned long) ((flags & MT_USERANDOM) ? get_random_number () : ntmpfiles++); | ||||
| 		(unsigned long) ((flags & MT_USERANDOM) ? random () : ntmpfiles++); | ||||
|       sprintf (filename, "%s/%s-%lu", tdir, lroot, filenum); | ||||
|       if (tmpnamelen > 0 && tmpnamelen < 32) | ||||
| 	filename[tdlen + 1 + tmpnamelen] = '\0'; | ||||
|  |  | |||
							
								
								
									
										188
									
								
								lib/sh/unicode.c
									
										
									
									
									
								
							
							
						
						
									
										188
									
								
								lib/sh/unicode.c
									
										
									
									
									
								
							|  | @ -1,6 +1,6 @@ | |||
| /* unicode.c - functions to convert unicode characters */ | ||||
| 
 | ||||
| /* Copyright (C) 2010 Free Software Foundation, Inc.
 | ||||
| /* Copyright (C) 2010-2012 Free Software Foundation, Inc.
 | ||||
| 
 | ||||
|    This file is part of GNU Bash, the Bourne Again SHell. | ||||
| 
 | ||||
|  | @ -28,6 +28,7 @@ | |||
| #ifdef HAVE_UNISTD_H | ||||
| #include <unistd.h> | ||||
| #endif | ||||
| #include <stdio.h> | ||||
| #include <limits.h> | ||||
| 
 | ||||
| #if HAVE_ICONV | ||||
|  | @ -61,6 +62,8 @@ static iconv_t localconv; | |||
| #endif | ||||
| 
 | ||||
| #ifndef HAVE_LOCALE_CHARSET | ||||
| static char charsetbuf[40]; | ||||
| 
 | ||||
| static char * | ||||
| stub_charset () | ||||
| { | ||||
|  | @ -68,32 +71,46 @@ stub_charset () | |||
| 
 | ||||
|   locale = get_locale_var ("LC_CTYPE"); | ||||
|   if (locale == 0 || *locale == 0) | ||||
|     return "ASCII"; | ||||
|     { | ||||
|       strcpy (charsetbuf, "ASCII"); | ||||
|       return charsetbuf; | ||||
|     } | ||||
|   s = strrchr (locale, '.'); | ||||
|   if (s) | ||||
|     { | ||||
|       t = strchr (s, '@'); | ||||
|       strcpy (charsetbuf, s+1); | ||||
|       t = strchr (charsetbuf, '@'); | ||||
|       if (t) | ||||
| 	*t = 0; | ||||
|       return ++s; | ||||
|       return charsetbuf; | ||||
|     } | ||||
|   else if (STREQ (locale, "UTF-8")) | ||||
|     return "UTF-8"; | ||||
|   else | ||||
|     return "ASCII"; | ||||
|   strcpy (charsetbuf, locale); | ||||
|   return charsetbuf; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| void | ||||
| u32reset () | ||||
| { | ||||
| #if defined (HAVE_ICONV) | ||||
|   if (u32init && localconv != (iconv_t)-1) | ||||
|     { | ||||
|       iconv_close (localconv); | ||||
|       localconv = (iconv_t)-1; | ||||
|     } | ||||
| #endif | ||||
|   u32init = 0; | ||||
|   utf8locale = 0; | ||||
| } | ||||
| 
 | ||||
| /* u32toascii ? */ | ||||
| int | ||||
| u32tochar (wc, s) | ||||
|      wchar_t wc; | ||||
| u32tochar (x, s) | ||||
|      unsigned long x; | ||||
|      char *s; | ||||
| { | ||||
|   unsigned long x; | ||||
|   int l; | ||||
| 
 | ||||
|   x = wc; | ||||
|   l = (x <= UCHAR_MAX) ? 1 : ((x <= USHORT_MAX) ? 2 : 4); | ||||
| 
 | ||||
|   if (x <= UCHAR_MAX) | ||||
|  | @ -115,31 +132,107 @@ u32tochar (wc, s) | |||
| } | ||||
| 
 | ||||
| int | ||||
| u32toutf8 (wc, s) | ||||
|      wchar_t wc; | ||||
| u32tocesc (wc, s) | ||||
|      u_bits32_t wc; | ||||
|      char *s; | ||||
| { | ||||
|   int l; | ||||
| 
 | ||||
|   l = (wc < 0x0080) ? 1 : ((wc < 0x0800) ? 2 : 3); | ||||
|   if (wc < 0x10000) | ||||
|     l = sprintf (s, "\\u%04X", wc); | ||||
|   else | ||||
|     l = sprintf (s, "\\u%08X", wc); | ||||
|   return l; | ||||
| } | ||||
| 
 | ||||
| /* Convert unsigned 32-bit int to utf-8 character string */ | ||||
| int | ||||
| u32toutf8 (wc, s) | ||||
|      u_bits32_t wc; | ||||
|      char *s; | ||||
| { | ||||
|   int l; | ||||
| 
 | ||||
|   if (wc < 0x0080) | ||||
|     s[0] = (unsigned char)wc; | ||||
|     { | ||||
|       s[0] = (char)wc; | ||||
|       l = 1; | ||||
|     } | ||||
|   else if (wc < 0x0800) | ||||
|     { | ||||
|       s[0] = (wc >> 6) | 0xc0; | ||||
|       s[1] = (wc & 0x3f) | 0x80; | ||||
|       l = 2; | ||||
|     } | ||||
|   else | ||||
|   else if (wc < 0x10000) | ||||
|     { | ||||
|       /* Technically, we could return 0 here if 0xd800 <= wc <= 0x0dfff */ | ||||
|       s[0] = (wc >> 12) | 0xe0; | ||||
|       s[1] = ((wc >> 6) & 0x3f) | 0x80; | ||||
|       s[2] = (wc & 0x3f) | 0x80; | ||||
|       l = 3; | ||||
|     } | ||||
|   else if (wc < 0x200000) | ||||
|     { | ||||
|       s[0] = (wc >> 18) | 0xf0; | ||||
|       s[1] = ((wc >> 12) & 0x3f) | 0x80; | ||||
|       s[2] = ((wc >>  6) & 0x3f) | 0x80; | ||||
|       s[3] = (wc & 0x3f) | 0x80; | ||||
|       l = 4; | ||||
|     } | ||||
|   /* Strictly speaking, UTF-8 doesn't have characters longer than 4 bytes */ | ||||
|   else if (wc < 0x04000000) | ||||
|     { | ||||
|       s[0] = (wc >> 24) | 0xf8; | ||||
|       s[1] = ((wc >> 18) & 0x3f) | 0x80; | ||||
|       s[2] = ((wc >> 12) & 0x3f) | 0x80; | ||||
|       s[3] = ((wc >>  6) & 0x3f) | 0x80; | ||||
|       s[4] = (wc & 0x3f) | 0x80; | ||||
|       l = 5; | ||||
|     } | ||||
|   else if (wc < 0x080000000) | ||||
|     { | ||||
|       s[0] = (wc >> 30) | 0xf8; | ||||
|       s[1] = ((wc >> 24) & 0x3f) | 0x80; | ||||
|       s[2] = ((wc >> 18) & 0x3f) | 0x80; | ||||
|       s[3] = ((wc >> 12) & 0x3f) | 0x80; | ||||
|       s[4] = ((wc >>  6) & 0x3f) | 0x80; | ||||
|       s[5] = (wc & 0x3f) | 0x80; | ||||
|       l = 6; | ||||
|     } | ||||
|   else | ||||
|     l = 0; | ||||
| 
 | ||||
|   s[l] = '\0'; | ||||
|   return l; | ||||
| } | ||||
| 
 | ||||
| /* Convert a 32-bit unsigned int (unicode) to a UTF-16 string.  Rarely used,
 | ||||
|    only if sizeof(wchar_t) == 2. */ | ||||
| int | ||||
| u32toutf16 (c, s) | ||||
|      u_bits32_t c; | ||||
|      unsigned short *s; | ||||
| { | ||||
|   int l; | ||||
| 
 | ||||
|   l = 0; | ||||
|   if (c < 0x0d800) | ||||
|     { | ||||
|       s[0] = (unsigned short) (c & 0xFFFF); | ||||
|       l = 1; | ||||
|     } | ||||
|   else if (c >= 0x0e000 && c <= 0x010ffff) | ||||
|     { | ||||
|       c -= 0x010000; | ||||
|       s[0] = (unsigned short)((c >> 10) + 0xd800); | ||||
|       s[1] = (unsigned short)((c & 0x3ff) + 0xdc00); | ||||
|       l = 2; | ||||
|     } | ||||
|   s[l] = 0; | ||||
|   return l; | ||||
| } | ||||
| 
 | ||||
| /* convert a single unicode-32 character into a multibyte string and put the
 | ||||
|    result in S, which must be large enough (at least MB_LEN_MAX bytes) */ | ||||
| int | ||||
|  | @ -148,6 +241,7 @@ u32cconv (c, s) | |||
|      char *s; | ||||
| { | ||||
|   wchar_t wc; | ||||
|   wchar_t ws[3]; | ||||
|   int n; | ||||
| #if HAVE_ICONV | ||||
|   const char *charset; | ||||
|  | @ -157,21 +251,23 @@ u32cconv (c, s) | |||
|   size_t sn; | ||||
| #endif | ||||
| 
 | ||||
|   wc = c; | ||||
| 
 | ||||
| #if __STDC_ISO_10646__ | ||||
|   if (sizeof (wchar_t) == 4) | ||||
|     { | ||||
|       n = wctomb (s, wc); | ||||
|       return n; | ||||
|     } | ||||
|   wc = c; | ||||
|   if (sizeof (wchar_t) == 4 && c <= 0x7fffffff) | ||||
|     n = wctomb (s, wc); | ||||
|   else if (sizeof (wchar_t) == 2 && c <= 0x10ffff && u32toutf16 (c, ws)) | ||||
|     n = wcstombs (s, ws, MB_LEN_MAX); | ||||
|   else | ||||
|     n = -1; | ||||
|   if (n != -1) | ||||
|     return n; | ||||
| #endif | ||||
| 
 | ||||
| #if HAVE_NL_LANGINFO | ||||
|   codeset = nl_langinfo (CODESET); | ||||
|   if (STREQ (codeset, "UTF-8")) | ||||
|     { | ||||
|       n = u32toutf8 (wc, s); | ||||
|       n = u32toutf8 (c, s); | ||||
|       return n; | ||||
|     } | ||||
| #endif | ||||
|  | @ -191,25 +287,23 @@ u32cconv (c, s) | |||
| 	{ | ||||
| 	  localconv = iconv_open (charset, "UTF-8"); | ||||
| 	  if (localconv == (iconv_t)-1) | ||||
| 	    localconv = iconv_open (charset, "ASCII"); | ||||
| 	    /* We assume ASCII when presented with an unknown encoding. */ | ||||
| 	    localconv = iconv_open ("ASCII", "UTF-8"); | ||||
| 	} | ||||
|       u32init = 1; | ||||
|     } | ||||
| 
 | ||||
|   /* If we have a UTF-8 locale, convert to UTF-8 and return converted value. */ | ||||
|   n = u32toutf8 (c, s); | ||||
|   if (utf8locale) | ||||
|     { | ||||
|       n = u32toutf8 (wc, s); | ||||
|       return n; | ||||
|     } | ||||
|     return n; | ||||
| 
 | ||||
|   /* If the conversion is not supported, even the ASCII requested above, we
 | ||||
|      bail now.  Currently we return the UTF-8 conversion.  We could return | ||||
|      u32tocesc(). */ | ||||
|   if (localconv == (iconv_t)-1) | ||||
|     { | ||||
|       n = u32tochar (wc, s); | ||||
|       return n; | ||||
|     } | ||||
| 
 | ||||
|   n = u32toutf8 (wc, s); | ||||
| 
 | ||||
|     return n; | ||||
|      | ||||
|   optr = obuf; | ||||
|   obytesleft = sizeof (obuf); | ||||
|   iptr = s; | ||||
|  | @ -218,7 +312,15 @@ u32cconv (c, s) | |||
|   iconv (localconv, NULL, NULL, NULL, NULL); | ||||
| 
 | ||||
|   if (iconv (localconv, (ICONV_CONST char **)&iptr, &sn, &optr, &obytesleft) == (size_t)-1) | ||||
|     return n;	/* You get utf-8 if iconv fails */ | ||||
|     { | ||||
| #if 1 | ||||
|       /* You get ISO C99 escape sequences if iconv fails */       | ||||
|       n = u32tocesc (c, s); | ||||
| #else | ||||
|       /* You get UTF-8 if iconv fails */ | ||||
| #endif | ||||
|       return n; | ||||
|     } | ||||
| 
 | ||||
|   *optr = '\0'; | ||||
| 
 | ||||
|  | @ -226,10 +328,14 @@ u32cconv (c, s) | |||
|      checking */ | ||||
|   strcpy (s, obuf); | ||||
|   return (optr - obuf); | ||||
| #endif | ||||
| #endif	/* HAVE_ICONV */ | ||||
| 
 | ||||
|   n = u32tochar (wc, s);	/* fallback */ | ||||
|   n = u32tocesc (c, s);	/* fallback is ISO C99 escape sequences */ | ||||
|   return n; | ||||
| } | ||||
| 
 | ||||
| #else | ||||
| void | ||||
| u32reset () | ||||
| { | ||||
| } | ||||
| #endif /* HANDLE_MULTIBYTE */ | ||||
|  |  | |||
							
								
								
									
										56
									
								
								lib/sh/wcsnwidth.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								lib/sh/wcsnwidth.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,56 @@ | |||
| /* wcsnwidth.c - compute display width of wide character string, up to max
 | ||||
| 		 specified width, return length. */ | ||||
| 
 | ||||
| /* Copyright (C) 2012 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> | ||||
| 
 | ||||
| #if defined (HANDLE_MULTIBYTE) | ||||
| 
 | ||||
| #include <stdc.h> | ||||
| #include <wchar.h> | ||||
| #include <bashansi.h> | ||||
| 
 | ||||
| /* Return the number of wide characters that will be displayed from wide string
 | ||||
|    PWCS.  If the display width exceeds MAX, return the number of wide chars | ||||
|    from PWCS required to display MAX characters on the screen. */ | ||||
| int | ||||
| wcsnwidth(pwcs, n, max) | ||||
|      const wchar_t *pwcs; | ||||
|      size_t n, max; | ||||
| { | ||||
|   wchar_t wc, *ws; | ||||
|   int len, l; | ||||
| 
 | ||||
|   len = 0; | ||||
|   ws = (wchar_t *)pwcs; | ||||
|   while (n-- > 0 && (wc = *ws++) != L'\0') | ||||
|     { | ||||
|       l = wcwidth (wc); | ||||
|       if (l < 0) | ||||
| 	return (-1); | ||||
|       else if (l == max - len) | ||||
|         return (ws - pwcs); | ||||
|       else if (l > max - len) | ||||
|         return (--ws - pwcs); | ||||
|       len += l; | ||||
|     } | ||||
|   return (ws - pwcs); | ||||
| } | ||||
| #endif | ||||
|  | @ -50,7 +50,7 @@ typedef ssize_t creadfunc_t __P((int, char *)); | |||
|    The differences are | ||||
|    	(1) using file descriptor instead of FILE *, | ||||
| 	(2) the order of arguments; the file descriptor comes the first, and | ||||
| 	(3) the addtion of thired argument, UNBUFFERED_READ; this argument | ||||
| 	(3) the addition of third argument, UNBUFFERED_READ; this argument | ||||
| 	    controls whether get_line uses buffering or not to get a byte data | ||||
| 	    from FD. get_line uses zreadc if UNBUFFERED_READ is zero; and | ||||
| 	    uses zread if UNBUFFERED_READ is non-zero. | ||||
|  |  | |||
|  | @ -66,11 +66,10 @@ zmapfd (fd, ostr, fn) | |||
| 	} | ||||
|       else if (nr < 0) | ||||
| 	{ | ||||
| 	  rval = -1; | ||||
| 	  free (result); | ||||
| 	  if (ostr) | ||||
| 	    *ostr = (char *)NULL; | ||||
| 	  break; | ||||
| 	  return -1; | ||||
| 	} | ||||
| 
 | ||||
|       RESIZE_MALLOCED_BUFFER (result, rind, nr, rsize, 128); | ||||
|  |  | |||
|  | @ -26,6 +26,7 @@ | |||
| #  include <unistd.h> | ||||
| #endif | ||||
| 
 | ||||
| #include <signal.h> | ||||
| #include <errno.h> | ||||
| 
 | ||||
| #if !defined (errno) | ||||
|  | @ -36,6 +37,9 @@ extern int errno; | |||
| #  define SEEK_CUR 1 | ||||
| #endif | ||||
| 
 | ||||
| extern void check_signals_and_traps (void); | ||||
| extern int signal_is_trapped (int); | ||||
| 
 | ||||
| /* Read LEN bytes from FD into BUF.  Retry the read on EINTR.  Any other
 | ||||
|    error causes the loop to break. */ | ||||
| ssize_t | ||||
|  | @ -46,8 +50,22 @@ zread (fd, buf, len) | |||
| { | ||||
|   ssize_t r; | ||||
| 
 | ||||
| #if 0 | ||||
| #if defined (HAVE_SIGINTERRUPT) | ||||
|   if (signal_is_trapped (SIGCHLD)) | ||||
|     siginterrupt (SIGCHLD, 1); | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
|   while ((r = read (fd, buf, len)) < 0 && errno == EINTR) | ||||
|     ; | ||||
|     check_signals_and_traps ();	/* XXX - should it be check_signals()? */ | ||||
| 
 | ||||
| #if 0 
 | ||||
| #if defined (HAVE_SIGINTERRUPT) | ||||
|   siginterrupt (SIGCHLD, 0); | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
|   return r; | ||||
| } | ||||
| 
 | ||||
|  | @ -148,6 +166,34 @@ zreadcintr (fd, cp) | |||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| /* Like zreadc, but read a specified number of characters at a time.  Used
 | ||||
|    for `read -N'. */ | ||||
| ssize_t | ||||
| zreadn (fd, cp, len) | ||||
|      int fd; | ||||
|      char *cp; | ||||
|      size_t len; | ||||
| { | ||||
|   ssize_t nr; | ||||
| 
 | ||||
|   if (lind == lused || lused == 0) | ||||
|     { | ||||
|       if (len > sizeof (lbuf)) | ||||
| 	len = sizeof (lbuf); | ||||
|       nr = zread (fd, lbuf, len); | ||||
|       lind = 0; | ||||
|       if (nr <= 0) | ||||
| 	{ | ||||
| 	  lused = 0; | ||||
| 	  return nr; | ||||
| 	} | ||||
|       lused = nr; | ||||
|     } | ||||
|   if (cp) | ||||
|     *cp = lbuf[lind++]; | ||||
|   return 1; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| zreset () | ||||
| { | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Chet Ramey
				Chet Ramey