Merge mozilla-central to mozilla-inbound

This commit is contained in:
Ed Morley 2012-07-03 10:30:34 +01:00
commit 6bdfdcc4c9
581 changed files with 274 additions and 1602 deletions

View File

@ -19,11 +19,8 @@ VISIBILITY_FLAGS =
# libstdc++-compat is not built yet.
STDCXX_COMPAT =
ifneq (WINNT,$(HOST_OS_ARCH))
HOST_PROGRAM = nsinstall$(HOST_BIN_SUFFIX)
ifeq (WINNT,$(HOST_OS_ARCH))
HOST_CSRCS = nsinstall_win.c
else
HOST_CSRCS = nsinstall.c pathsub.c
endif

View File

@ -633,19 +633,34 @@ endif
PWD := $(CURDIR)
endif
NSINSTALL_PY := $(PYTHON) $(call core_abspath,$(topsrcdir)/config/nsinstall.py)
# For Pymake, wherever we use nsinstall.py we're also going to try to make it
# a native command where possible. Since native commands can't be used outside
# of single-line commands, we continue to provide INSTALL for general use.
# Single-line commands should be switched over to install_cmd.
NSINSTALL_NATIVECMD := %nsinstall nsinstall
ifdef NSINSTALL_BIN
NSINSTALL = $(NSINSTALL_BIN)
else
ifeq (OS2,$(CROSS_COMPILE)$(OS_ARCH))
NSINSTALL = $(MOZ_TOOLS_DIR)/nsinstall
else
ifeq ($(HOST_OS_ARCH),WINNT)
NSINSTALL = $(NSINSTALL_PY)
else
NSINSTALL = $(CONFIG_TOOLS)/nsinstall$(HOST_BIN_SUFFIX)
endif # WINNT
endif # OS2
endif # NSINSTALL_BIN
ifeq (,$(CROSS_COMPILE)$(filter-out WINNT OS2, $(OS_ARCH)))
INSTALL = $(NSINSTALL)
INSTALL = $(NSINSTALL) -t
ifdef .PYMAKE
install_cmd = $(NSINSTALL_NATIVECMD) -t $(1)
endif # .PYMAKE
else
# This isn't laid out as conditional directives so that NSDISTMODE can be
@ -654,16 +669,17 @@ INSTALL = $(if $(filter copy, $(NSDISTMODE)), $(NSINSTALL) -t, $(if $(fi
endif # WINNT/OS2
# The default for install_cmd is simply INSTALL
install_cmd ?= $(INSTALL) $(1)
# Use nsinstall in copy mode to install files on the system
SYSINSTALL = $(NSINSTALL) -t
# This isn't necessarily true, just here
sysinstall_cmd = install_cmd
# Directory nsinstall. Windows and OS/2 nsinstall can't recursively copy
# directories.
ifneq (,$(filter WINNT os2-emx,$(HOST_OS_ARCH)))
DIR_INSTALL = $(PYTHON) $(topsrcdir)/config/nsinstall.py
else
# Directory nsinstall.
DIR_INSTALL = $(INSTALL)
endif # WINNT/OS2
dir_install_cmd = install_cmd
#
# Localization build automation

View File

@ -46,13 +46,13 @@ xpidl-install-src-preqs=\
$(NULL)
xpidl-install-src: $(xpidl-install-src-preqs)
$(INSTALL) $(IFLAGS1) $(foreach val,$^,$(call mkdir_stem,$(val)))
$(call install_cmd,$(IFLAGS1) $(foreach val,$^,$(call mkdir_stem,$(val))))
xpidl-install-headers-preqs =\
$(patsubst %.idl,$(XPIDL_GEN_DIR)/%.h, $(XPIDLSRCS)) \
$(call mkdir_deps,$(DIST)/include) \
$(NULL)
xpidl-install-headers: $(xpidl-install-headers-preqs)
$(INSTALL) $(IFLAGS1) $(foreach val,$^,$(call mkdir_stem,$(val)))
$(call install_cmd,$(IFLAGS1) $(foreach val,$^,$(call mkdir_stem,$(val))))
endif #} _xpidl-todo_

View File

@ -15,8 +15,9 @@ import os
import os.path
import sys
import shutil
import stat
def nsinstall(argv):
def _nsinstall_internal(argv):
usage = "usage: %prog [options] arg1 [arg2 ...] target-directory"
p = OptionParser(usage=usage)
@ -61,36 +62,47 @@ def nsinstall(argv):
return 1
# just create one directory?
if options.D:
if len(args) != 1:
def maybe_create_dir(dir, mode, try_again):
if os.path.exists(dir):
if not os.path.isdir(dir):
print >> sys.stderr, ('nsinstall: %s is not a directory' % dir)
return 1
if mode:
os.chmod(dir, mode)
return 0
try:
if mode:
os.makedirs(dir, mode)
else:
os.makedirs(dir)
except Exception, e:
# We might have hit EEXIST due to a race condition (see bug 463411) -- try again once
if try_again:
return maybe_create_dir(dir, mode, False)
print >> sys.stderr, ("nsinstall: failed to create directory %s: %s" % (dir, e))
return 1
if os.path.exists(args[0]):
if not os.path.isdir(args[0]):
sys.stderr.write('nsinstall: ' + args[0] + ' is not a directory\n')
sys.exit(1)
if options.m:
os.chmod(args[0], options.m)
sys.exit()
if options.m:
os.makedirs(args[0], options.m)
else:
os.makedirs(args[0])
return 0
return 0
if options.X:
options.X = [os.path.abspath(p) for p in options.X]
if options.D:
return maybe_create_dir(args[0], options.m, True)
# nsinstall arg1 [...] directory
if len(args) < 2:
p.error('not enough arguments')
def copy_all_entries(entries, target):
for e in entries:
if options.X and os.path.abspath(e) in options.X:
e = os.path.abspath(e)
if options.X and e in options.X:
continue
dest = os.path.join(target,
os.path.basename(os.path.normpath(e)))
dest = os.path.join(target, os.path.basename(e))
dest = os.path.abspath(dest)
handleTarget(e, dest)
if options.m:
os.chmod(dest, options.m)
@ -112,19 +124,57 @@ def nsinstall(argv):
# options.t is not relevant for directories
if options.m:
os.chmod(targetpath, options.m)
elif options.t:
shutil.copy2(srcpath, targetpath)
else:
shutil.copy(srcpath, targetpath)
if os.path.exists(targetpath):
# On Windows, read-only files can't be deleted
os.chmod(targetpath, stat.S_IWUSR)
os.remove(targetpath)
if options.t:
shutil.copy2(srcpath, targetpath)
else:
shutil.copy(srcpath, targetpath)
# the last argument is the target directory
target = args.pop()
# ensure target directory
if not os.path.isdir(target):
os.makedirs(target)
# ensure target directory (importantly, we do not apply a mode to the directory
# because we want to copy files into it and the mode might be read-only)
rv = maybe_create_dir(target, None, True)
if rv != 0:
return rv
copy_all_entries(args, target)
return 0
# nsinstall as a native command is always UTF-8
def nsinstall(argv):
return _nsinstall_internal([unicode(arg, "utf-8") for arg in argv])
if __name__ == '__main__':
sys.exit(nsinstall(sys.argv[1:]))
# sys.argv corrupts characters outside the system code page on Windows
# <http://bugs.python.org/issue2128>. Use ctypes instead. This is also
# useful because switching to Unicode strings makes python use the wide
# Windows APIs, which is what we want here since the wide APIs normally do a
# better job at handling long paths and such.
if sys.platform == "win32":
import ctypes
from ctypes import wintypes
GetCommandLine = ctypes.windll.kernel32.GetCommandLineW
GetCommandLine.argtypes = []
GetCommandLine.restype = wintypes.LPWSTR
CommandLineToArgv = ctypes.windll.shell32.CommandLineToArgvW
CommandLineToArgv.argtypes = [wintypes.LPWSTR, ctypes.POINTER(ctypes.c_int)]
CommandLineToArgv.restype = ctypes.POINTER(wintypes.LPWSTR)
argc = ctypes.c_int(0)
argv_arr = CommandLineToArgv(GetCommandLine(), ctypes.byref(argc))
# The first argv will be "python", the second will be the .py file
argv = argv_arr[1:argc.value]
else:
# For consistency, do it on Unix as well
if sys.stdin.encoding is not None:
argv = [unicode(arg, sys.stdin.encoding) for arg in sys.argv]
else:
argv = [unicode(arg) for arg in sys.argv]
sys.exit(_nsinstall_internal(argv[1:]))

View File

@ -1,747 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* The nsinstall command for Win32
*
* Our gmake makefiles use the nsinstall command to create the
* object directories or installing headers and libs. This code was originally
* taken from shmsdos.c
*/
#include <direct.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <windows.h>
#pragma hdrstop
/*
* sh_FileFcn --
*
* A function that operates on a file. The pathname is either
* absolute or relative to the current directory, and contains
* no wildcard characters such as * and ?. Additional arguments
* can be passed to the function via the arg pointer.
*/
typedef BOOL (*sh_FileFcn)(
wchar_t *pathName,
WIN32_FIND_DATA *fileData,
void *arg);
static int shellCp (wchar_t **pArgv);
static int shellNsinstall (wchar_t **pArgv);
static int shellMkdir (wchar_t **pArgv);
static BOOL sh_EnumerateFiles(const wchar_t *pattern, const wchar_t *where,
sh_FileFcn fileFcn, void *arg, int *nFiles);
static const char *sh_GetLastErrorMessage(void);
static BOOL sh_DoCopy(wchar_t *srcFileName, DWORD srcFileAttributes,
wchar_t *dstFileName, DWORD dstFileAttributes,
int force, int recursive);
#define LONGPATH_PREFIX L"\\\\?\\"
#define ARRAY_LEN(a) (sizeof(a) / sizeof(a[0]))
#define STR_LEN(a) (ARRAY_LEN(a) - 1)
#ifdef __MINGW32__
/* MingW currently does not implement a wide version of the
startup routines. Workaround is to implement something like
it ourselves. */
#include <shellapi.h>
int wmain(int argc, WCHAR **argv);
int main(int argc, char **argv)
{
int result;
wchar_t *commandLine = GetCommandLineW();
int argcw = 0;
wchar_t **_argvw = CommandLineToArgvW( commandLine, &argcw );
wchar_t *argvw[argcw + 1];
int i;
if (!_argvw)
return 127;
/* CommandLineToArgvW doesn't output the ending NULL so
we have to manually add it on */
for ( i = 0; i < argcw; i++ )
argvw[i] = _argvw[i];
argvw[argcw] = NULL;
result = wmain(argcw, argvw);
LocalFree(_argvw);
return result;
}
#endif /* __MINGW32__ */
/* changes all forward slashes in token to backslashes */
void changeForwardSlashesToBackSlashes ( wchar_t *arg )
{
if ( arg == NULL )
return;
while ( *arg ) {
if ( *arg == '/' )
*arg = '\\';
arg++;
}
}
int wmain(int argc, wchar_t *argv[ ])
{
return shellNsinstall ( argv + 1 );
}
static int
shellNsinstall (wchar_t **pArgv)
{
int retVal = 0; /* exit status */
int dirOnly = 0; /* 1 if and only if -D is specified */
wchar_t **pSrc;
wchar_t **pDst;
/*
* Process the command-line options. We ignore the
* options except for -D. Some options, such as -m,
* are followed by an argument. We need to skip the
* argument too.
*/
while ( *pArgv && **pArgv == '-' ) {
wchar_t c = (*pArgv)[1]; /* The char after '-' */
if ( c == 'D' ) {
dirOnly = 1;
} else if ( c == 'm' ) {
pArgv++; /* skip the next argument */
}
pArgv++;
}
if ( !dirOnly ) {
/* There are files to install. Get source files */
if ( *pArgv ) {
pSrc = pArgv++;
} else {
fprintf( stderr, "nsinstall: not enough arguments\n");
return 3;
}
}
/* Get to last token to find destination directory */
if ( *pArgv ) {
pDst = pArgv++;
if ( dirOnly && *pArgv ) {
fprintf( stderr, "nsinstall: too many arguments with -D\n");
return 3;
}
} else {
fprintf( stderr, "nsinstall: not enough arguments\n");
return 3;
}
while ( *pArgv )
pDst = pArgv++;
retVal = shellMkdir ( pDst );
if ( retVal )
return retVal;
if ( !dirOnly )
retVal = shellCp ( pSrc );
return retVal;
}
static int
shellMkdir (wchar_t **pArgv)
{
int retVal = 0; /* assume valid return */
wchar_t *arg;
wchar_t *pArg;
wchar_t path[_MAX_PATH];
wchar_t tmpPath[_MAX_PATH];
wchar_t *pTmpPath = tmpPath;
/* All the options are simply ignored in this implementation */
while ( *pArgv && **pArgv == '-' ) {
if ( (*pArgv)[1] == 'm' ) {
pArgv++; /* skip the next argument (mode) */
}
pArgv++;
}
while ( *pArgv ) {
arg = *pArgv;
changeForwardSlashesToBackSlashes ( arg );
pArg = arg;
pTmpPath = tmpPath;
while ( 1 ) {
/* create part of path */
while ( *pArg ) {
*pTmpPath++ = *pArg++;
if ( *pArg == '\\' )
break;
}
*pTmpPath = '\0';
/* check if directory already exists */
_wgetcwd ( path, _MAX_PATH );
if ( _wchdir ( tmpPath ) == -1 &&
_wmkdir ( tmpPath ) == -1 && // might have hit EEXIST
_wchdir ( tmpPath ) == -1) { // so try again
char buf[2048];
_snprintf(buf, 2048, "Could not create the directory: %S",
tmpPath);
perror ( buf );
retVal = 3;
break;
} else {
// get back to the cwd
_wchdir ( path );
}
if ( *pArg == '\0' ) /* complete path? */
break;
/* loop for next directory */
}
pArgv++;
}
return retVal;
}
static const char *
sh_GetLastErrorMessage()
{
static char buf[128];
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* default language */
buf,
sizeof(buf),
NULL
);
return buf;
}
/*
* struct sh_FileData --
*
* A pointer to the sh_FileData structure is passed into sh_RecordFileData,
* which will fill in the fields.
*/
struct sh_FileData {
wchar_t pathName[_MAX_PATH];
DWORD dwFileAttributes;
};
/*
* sh_RecordFileData --
*
* Record the pathname and attributes of the file in
* the sh_FileData structure pointed to by arg.
*
* Always return TRUE (successful completion).
*
* This function is intended to be passed into sh_EnumerateFiles
* to see if a certain pattern expands to exactly one file/directory,
* and if so, record its pathname and attributes.
*/
static BOOL
sh_RecordFileData(wchar_t *pathName, WIN32_FIND_DATA *findData, void *arg)
{
struct sh_FileData *fData = (struct sh_FileData *) arg;
wcscpy(fData->pathName, pathName);
fData->dwFileAttributes = findData->dwFileAttributes;
return TRUE;
}
static BOOL
sh_DoCopy(wchar_t *srcFileName,
DWORD srcFileAttributes,
wchar_t *dstFileName,
DWORD dstFileAttributes,
int force,
int recursive
)
{
if (dstFileAttributes != 0xFFFFFFFF) {
if ((dstFileAttributes & FILE_ATTRIBUTE_READONLY) && force) {
dstFileAttributes &= ~FILE_ATTRIBUTE_READONLY;
SetFileAttributes(dstFileName, dstFileAttributes);
}
}
if (srcFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
fprintf(stderr, "nsinstall: %ls is a directory\n",
srcFileName);
return FALSE;
} else {
DWORD r;
wchar_t longSrc[1004] = LONGPATH_PREFIX;
wchar_t longDst[1004] = LONGPATH_PREFIX;
r = GetFullPathName(srcFileName, 1000, longSrc + STR_LEN(LONGPATH_PREFIX), NULL);
if (!r) {
fprintf(stderr, "nsinstall: couldn't get full path of %ls: %s\n",
srcFileName, sh_GetLastErrorMessage());
return FALSE;
}
r = GetFullPathName(dstFileName, 1000, longDst + ARRAY_LEN(LONGPATH_PREFIX) - 1, NULL);
if (!r) {
fprintf(stderr, "nsinstall: couldn't get full path of %ls: %s\n",
dstFileName, sh_GetLastErrorMessage());
return FALSE;
}
if (!CopyFile(longSrc, longDst, FALSE)) {
fprintf(stderr, "nsinstall: cannot copy %ls to %ls: %s\n",
srcFileName, dstFileName, sh_GetLastErrorMessage());
return FALSE;
}
}
return TRUE;
}
/*
* struct sh_CpCmdArg --
*
* A pointer to the sh_CpCmdArg structure is passed into sh_CpFileCmd.
* The sh_CpCmdArg contains information about the cp command, and
* provide a buffer for constructing the destination file name.
*/
struct sh_CpCmdArg {
int force; /* -f option, ok to overwrite an existing
* read-only destination file */
int recursive; /* -r or -R option, recursively copy
* directories. Note: this field is not used
* by nsinstall and should always be 0. */
wchar_t *dstFileName; /* a buffer for constructing the destination
* file name */
wchar_t *dstFileNameMarker; /* points to where in the dstFileName buffer
* we should write the file component of the
* destination file */
};
/*
* sh_CpFileCmd --
*
* Copy a file to the destination directory
*
* This function is intended to be passed into sh_EnumerateFiles to
* copy all the files specified by the pattern to the destination
* directory.
*
* Return TRUE if the file is successfully copied, and FALSE otherwise.
*/
static BOOL
sh_CpFileCmd(wchar_t *pathName, WIN32_FIND_DATA *findData, void *cpArg)
{
BOOL retVal = TRUE;
struct sh_CpCmdArg *arg = (struct sh_CpCmdArg *) cpArg;
wcscpy(arg->dstFileNameMarker, findData->cFileName);
return sh_DoCopy(pathName, findData->dwFileAttributes,
arg->dstFileName, GetFileAttributes(arg->dstFileName),
arg->force, arg->recursive);
}
static int
shellCp (wchar_t **pArgv)
{
int retVal = 0;
wchar_t **pSrc;
wchar_t **pDst;
struct sh_CpCmdArg arg;
struct sh_FileData dstData;
int dstIsDir = 0;
int n;
arg.force = 0;
arg.recursive = 0;
arg.dstFileName = dstData.pathName;
arg.dstFileNameMarker = 0;
while (*pArgv && **pArgv == '-') {
wchar_t *p = *pArgv;
while (*(++p)) {
if (*p == 'f') {
arg.force = 1;
}
}
pArgv++;
}
/* the first source file */
if (*pArgv) {
pSrc = pArgv++;
} else {
fprintf(stderr, "nsinstall: not enough arguments\n");
return 3;
}
/* get to the last token to find destination */
if (*pArgv) {
pDst = pArgv++;
} else {
fprintf(stderr, "nsinstall: not enough arguments\n");
return 3;
}
while (*pArgv) {
pDst = pArgv++;
}
/*
* The destination pattern must unambiguously expand to exactly
* one file or directory.
*/
changeForwardSlashesToBackSlashes(*pDst);
sh_EnumerateFiles(*pDst, *pDst, sh_RecordFileData, &dstData, &n);
assert(n >= 0);
if (n == 1) {
/*
* Is the destination a file or directory?
*/
if (dstData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
dstIsDir = 1;
}
} else if (n > 1) {
fprintf(stderr, "nsinstall: %ls: ambiguous destination file "
"or directory\n", *pDst);
return 3;
} else {
/*
* n == 0, meaning that destination file or directory does
* not exist. In this case the destination file directory
* name must be fully specified.
*/
wchar_t *p;
for (p = *pDst; *p; p++) {
if (*p == '*' || *p == '?') {
fprintf(stderr, "nsinstall: %ls: No such file or directory\n",
*pDst);
return 3;
}
}
/*
* Do not include the trailing \, if any, unless it is a root
* directory (\ or X:\).
*/
if (p > *pDst && p[-1] == '\\' && p != *pDst + 1 && p[-2] != ':') {
p[-1] = '\0';
}
wcscpy(dstData.pathName, *pDst);
dstData.dwFileAttributes = 0xFFFFFFFF;
}
/*
* If there are two or more source files, the destination has
* to be a directory.
*/
if (pDst - pSrc > 1 && !dstIsDir) {
fprintf(stderr, "nsinstall: cannot copy more than"
" one file to the same destination file\n");
return 3;
}
if (dstIsDir) {
arg.dstFileNameMarker = arg.dstFileName + wcslen(arg.dstFileName);
/*
* Now arg.dstFileNameMarker is pointing to the null byte at the
* end of string. We want to make sure that there is a \ at the
* end of string, and arg.dstFileNameMarker should point right
* after that \.
*/
if (arg.dstFileNameMarker[-1] != '\\') {
*(arg.dstFileNameMarker++) = '\\';
}
}
if (!dstIsDir) {
struct sh_FileData srcData;
assert(pDst - pSrc == 1);
changeForwardSlashesToBackSlashes(*pSrc);
sh_EnumerateFiles(*pSrc, *pSrc, sh_RecordFileData, &srcData, &n);
if (n == 0) {
fprintf(stderr, "nsinstall: %ls: No such file or directory\n",
*pSrc);
retVal = 3;
} else if (n > 1) {
fprintf(stderr, "nsinstall: cannot copy more than one file or "
"directory to the same destination\n");
retVal = 3;
} else {
assert(n == 1);
if (sh_DoCopy(srcData.pathName, srcData.dwFileAttributes,
dstData.pathName, dstData.dwFileAttributes,
arg.force, arg.recursive) == FALSE) {
retVal = 3;
}
}
return retVal;
}
for ( ; *pSrc != *pDst; pSrc++) {
BOOL rv;
changeForwardSlashesToBackSlashes(*pSrc);
rv = sh_EnumerateFiles(*pSrc, *pSrc, sh_CpFileCmd, &arg, &n);
if (rv == FALSE) {
retVal = 3;
} else {
if (n == 0) {
fprintf(stderr, "nsinstall: %ls: No such file or directory\n",
*pSrc);
retVal = 3;
}
}
}
return retVal;
}
/*
* sh_EnumerateFiles --
*
* Enumerate all the files in the specified pattern, which is a pathname
* containing possibly wildcard characters such as * and ?. fileFcn
* is called on each file, passing the expanded file name, a pointer
* to the file's WIN32_FILE_DATA, and the arg pointer.
*
* It is assumed that there are no wildcard characters before the
* character pointed to by 'where'.
*
* On return, *nFiles stores the number of files enumerated. *nFiles is
* set to this number whether sh_EnumerateFiles or 'fileFcn' succeeds
* or not.
*
* Return TRUE if the files are successfully enumerated and all
* 'fileFcn' invocations succeeded. Return FALSE if something went
* wrong.
*/
static BOOL sh_EnumerateFiles(
const wchar_t *pattern,
const wchar_t *where,
sh_FileFcn fileFcn,
void *arg,
int *nFiles
)
{
WIN32_FIND_DATA fileData;
HANDLE hSearch;
const wchar_t *src;
wchar_t *dst;
wchar_t fileName[_MAX_PATH];
wchar_t *fileNameMarker = fileName;
wchar_t *oldFileNameMarker;
BOOL hasWildcard = FALSE;
BOOL retVal = TRUE;
BOOL patternEndsInDotStar = FALSE;
BOOL patternEndsInDot = FALSE; /* a special case of
* patternEndsInDotStar */
int numDotsInPattern;
int len;
/*
* Windows expands patterns ending in ".", ".*", ".**", etc.
* differently from the glob expansion on Unix. For example,
* both "foo." and "foo.*" match "foo", and "*.*" matches
* everything, including filenames with no dots. So we need
* to throw away extra files returned by the FindNextFile()
* function. We require that a matched filename have at least
* the number of dots in the pattern.
*/
len = wcslen(pattern);
if (len >= 2) {
/* Start from the end of pattern and go backward */
const wchar_t *p = &pattern[len - 1];
/* We can have zero or more *'s */
while (p >= pattern && *p == '*') {
p--;
}
if (p >= pattern && *p == '.') {
patternEndsInDotStar = TRUE;
if (p == &pattern[len - 1]) {
patternEndsInDot = TRUE;
}
p--;
numDotsInPattern = 1;
while (p >= pattern && *p != '\\') {
if (*p == '.') {
numDotsInPattern++;
}
p--;
}
}
}
*nFiles = 0;
/*
* Copy pattern to fileName, but only up to and not including
* the first \ after the first wildcard letter.
*
* Make fileNameMarker point to one of the following:
* - the start of fileName, if fileName does not contain any \.
* - right after the \ before the first wildcard letter, if there is
* a wildcard character.
* - right after the last \, if there is no wildcard character.
*/
dst = fileName;
src = pattern;
while (src < where) {
if (*src == '\\') {
oldFileNameMarker = fileNameMarker;
fileNameMarker = dst + 1;
}
*(dst++) = *(src++);
}
while (*src && *src != '*' && *src != '?') {
if (*src == '\\') {
oldFileNameMarker = fileNameMarker;
fileNameMarker = dst + 1;
}
*(dst++) = *(src++);
}
if (*src) {
/*
* Must have seen the first wildcard letter
*/
hasWildcard = TRUE;
while (*src && *src != '\\') {
*(dst++) = *(src++);
}
}
/* Now src points to either null or \ */
assert(*src == '\0' || *src == '\\');
assert(hasWildcard || *src == '\0');
*dst = '\0';
/*
* If the pattern does not contain any wildcard characters, then
* we don't need to go the FindFirstFile route.
*/
if (!hasWildcard) {
/*
* See if it is the root directory, \, or X:\.
*/
assert(!wcscmp(fileName, pattern));
assert(wcslen(fileName) >= 1);
if (dst[-1] == '\\' && (dst == fileName + 1 || dst[-2] == ':')) {
fileData.cFileName[0] = '\0';
} else {
/*
* Do not include the trailing \, if any
*/
if (dst[-1] == '\\') {
assert(*fileNameMarker == '\0');
dst[-1] = '\0';
fileNameMarker = oldFileNameMarker;
}
wcscpy(fileData.cFileName, fileNameMarker);
}
fileData.dwFileAttributes = GetFileAttributes(fileName);
if (fileData.dwFileAttributes == 0xFFFFFFFF) {
return TRUE;
}
*nFiles = 1;
return (*fileFcn)(fileName, &fileData, arg);
}
hSearch = FindFirstFile(fileName, &fileData);
if (hSearch == INVALID_HANDLE_VALUE) {
return retVal;
}
do {
if (!wcscmp(fileData.cFileName, L".")
|| !wcscmp(fileData.cFileName, L"..")) {
/*
* Skip over . and ..
*/
continue;
}
if (patternEndsInDotStar) {
int nDots = 0;
wchar_t *p = fileData.cFileName;
while (*p) {
if (*p == '.') {
nDots++;
}
p++;
}
/* Now p points to the null byte at the end of file name */
if (patternEndsInDot && (p == fileData.cFileName
|| p[-1] != '.')) {
/*
* File name does not end in dot. Skip this file.
* Note: windows file name probably cannot end in dot,
* but we do this check anyway.
*/
continue;
}
if (nDots < numDotsInPattern) {
/*
* Not enough dots in file name. Must be an extra
* file in matching .* pattern. Skip this file.
*/
continue;
}
}
wcscpy(fileNameMarker, fileData.cFileName);
if (*src && *(src + 1)) {
/*
* More to go. Recurse.
*/
int n;
assert(*src == '\\');
where = fileName + wcslen(fileName);
wcscat(fileName, src);
sh_EnumerateFiles(fileName, where, fileFcn, arg, &n);
*nFiles += n;
} else {
assert(wcschr(fileName, '*') == NULL);
assert(wcschr(fileName, '?') == NULL);
(*nFiles)++;
if ((*fileFcn)(fileName, &fileData, arg) == FALSE) {
retVal = FALSE;
}
}
} while (FindNextFile(hSearch, &fileData));
FindClose(hSearch);
return retVal;
}

View File

@ -1190,14 +1190,14 @@ endif
ifndef NO_DIST_INSTALL
ifneq (,$(EXPORTS))
export:: $(EXPORTS)
$(INSTALL) $(IFLAGS1) $^ $(DIST)/include
$(call install_cmd,$(IFLAGS1) $^ $(DIST)/include)
endif
endif # NO_DIST_INSTALL
define EXPORT_NAMESPACE_RULE
ifndef NO_DIST_INSTALL
export:: $(EXPORTS_$(namespace))
$(INSTALL) $(IFLAGS1) $$^ $(DIST)/include/$(namespace)
$(call install_cmd,$(IFLAGS1) $$^ $(DIST)/include/$(namespace))
endif # NO_DIST_INSTALL
endef
@ -1246,7 +1246,7 @@ $(FINAL_TARGET)/defaults/autoconfig::
ifndef NO_DIST_INSTALL
export:: $(AUTOCFG_JS_EXPORTS) $(FINAL_TARGET)/defaults/autoconfig
$(INSTALL) $(IFLAGS1) $^
$(call install_cmd,$(IFLAGS1) $^)
endif
endif
@ -1312,7 +1312,7 @@ endif # XPIDL_MODULE.xpt != XPIDLSRCS
libs:: $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt
ifndef NO_DIST_INSTALL
$(INSTALL) $(IFLAGS1) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(FINAL_TARGET)/components
$(call install_cmd,$(IFLAGS1) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt $(FINAL_TARGET)/components)
ifndef NO_INTERFACES_MANIFEST
@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/interfaces.manifest "interfaces $(XPIDL_MODULE).xpt"
@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/interfaces.manifest"
@ -1340,7 +1340,7 @@ export-idl:: $(SUBMAKEFILES) $(MAKE_DIRS)
ifneq ($(XPIDLSRCS),)
ifndef NO_DIST_INSTALL
export-idl:: $(XPIDLSRCS) $(IDL_DIR)
$(INSTALL) $(IFLAGS1) $^
$(call install_cmd,$(IFLAGS1) $^)
endif
endif
$(LOOP_OVER_PARALLEL_DIRS)
@ -1360,7 +1360,7 @@ endif
ifdef EXTRA_COMPONENTS
libs:: $(EXTRA_COMPONENTS)
ifndef NO_DIST_INSTALL
$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/components
$(call install_cmd,$(IFLAGS1) $^ $(FINAL_TARGET)/components)
endif
endif
@ -1390,7 +1390,7 @@ endif
ifdef EXTRA_JS_MODULES
libs:: $(EXTRA_JS_MODULES)
ifndef NO_DIST_INSTALL
$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/modules
$(call install_cmd,$(IFLAGS1) $^ $(FINAL_TARGET)/modules)
endif
endif
@ -1423,7 +1423,7 @@ GENERATED_DIRS += $(testmodulesdir)
libs:: $(TESTING_JS_MODULES)
ifndef NO_DIST_INSTALL
$(INSTALL) $(IFLAGS) $^ $(testmodulesdir)
$(call install_cmd,$(IFLAGS) $^ $(testmodulesdir))
endif
endif
@ -1437,7 +1437,7 @@ $(SDK_LIB_DIR)::
ifndef NO_DIST_INSTALL
libs:: $(SDK_LIBRARY) $(SDK_LIB_DIR)
$(INSTALL) $(IFLAGS2) $^
$(call install_cmd,$(IFLAGS2) $^)
endif
endif # SDK_LIBRARY
@ -1448,7 +1448,7 @@ $(SDK_BIN_DIR)::
ifndef NO_DIST_INSTALL
libs:: $(SDK_BINARY) $(SDK_BIN_DIR)
$(INSTALL) $(IFLAGS2) $^
$(call install_cmd,$(IFLAGS2) $^)
endif
endif # SDK_BINARY

View File

@ -4,8 +4,18 @@ import os, sys, os.path, time
from tempfile import mkdtemp
from shutil import rmtree
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from mozprocess import processhandler
from nsinstall import nsinstall
import nsinstall as nsinstall_module
NSINSTALL_PATH = nsinstall_module.__file__
# Run the non-ASCII tests on (a) Windows, or (b) any platform with
# sys.stdin.encoding set to UTF-8
import codecs
RUN_NON_ASCII_TESTS = (sys.platform == "win32" or
(sys.stdin.encoding is not None and
codecs.lookup(sys.stdin.encoding) == codecs.lookup("utf-8")))
class TestNsinstall(unittest.TestCase):
"""
@ -15,7 +25,13 @@ class TestNsinstall(unittest.TestCase):
self.tmpdir = mkdtemp()
def tearDown(self):
rmtree(self.tmpdir)
# Unicode strings means non-ASCII children can be deleted properly on
# Windows
if sys.stdin.encoding is None:
tmpdir = unicode(self.tmpdir)
else:
tmpdir = unicode(self.tmpdir, sys.stdin.encoding)
rmtree(tmpdir)
# utility methods for tests
def touch(self, file, dir=None):
@ -121,6 +137,36 @@ class TestNsinstall(unittest.TestCase):
self.assertEqual(nsinstall(["-d", testfile, destdir]), 0)
self.assert_(os.path.isdir(os.path.join(destdir, "testfile")))
if RUN_NON_ASCII_TESTS:
def test_nsinstall_non_ascii(self):
"Test that nsinstall handles non-ASCII files"
filename = u"\u2325\u3452\u2415\u5081"
testfile = self.touch(filename)
testdir = self.mkdirs(u"\u4241\u1D04\u1414")
self.assertEqual(nsinstall([testfile.encode("utf-8"),
testdir.encode("utf-8")]), 0)
destfile = os.path.join(testdir, filename)
self.assert_(os.path.isfile(destfile))
def test_nsinstall_non_ascii_subprocess(self):
"Test that nsinstall as a subprocess handles non-ASCII files"
filename = u"\u2325\u3452\u2415\u5081"
testfile = self.touch(filename)
testdir = self.mkdirs(u"\u4241\u1D04\u1414")
# We don't use subprocess because it can't handle Unicode on
# Windows <http://bugs.python.org/issue1759845>. mozprocess calls
# CreateProcessW directly so it's perfect.
p = processhandler.ProcessHandlerMixin([sys.executable,
NSINSTALL_PATH,
testfile, testdir])
p.run()
rv = p.waitForFinish()
self.assertEqual(rv, 0)
destfile = os.path.join(testdir, filename)
self.assert_(os.path.isfile(destfile))
#TODO: implement -R, -l, -L and test them!
if __name__ == '__main__':

View File

@ -338,7 +338,7 @@ let DOMApplicationRegistry = {
let tmp = [];
let id = this._appId(aData.origin);
if (id && this._isLaunchable(aData.origin)) {
if (id && this._isLaunchable(this.webapps[id].origin)) {
let app = this._cloneAppObject(this.webapps[id]);
aData.apps.push(app);
tmp.push({ id: id });
@ -357,7 +357,7 @@ let DOMApplicationRegistry = {
for (let id in this.webapps) {
if (this.webapps[id].installOrigin == aData.origin &&
this._isLaunchable(aData.origin)) {
this._isLaunchable(this.webapps[id].origin)) {
aData.apps.push(this._cloneAppObject(this.webapps[id]));
tmp.push({ id: id });
}
@ -376,7 +376,7 @@ let DOMApplicationRegistry = {
for (let id in this.webapps) {
if (this.webapps[id].installOrigin == aData.origin &&
!this._isLaunchable(aData.origin)) {
!this._isLaunchable(this.webapps[id].origin)) {
aData.apps.push(this._cloneAppObject(this.webapps[id]));
tmp.push({ id: id });
}
@ -395,7 +395,7 @@ let DOMApplicationRegistry = {
for (let id in this.webapps) {
let app = this._cloneAppObject(this.webapps[id]);
if (!this._isLaunchable(app.installOrigin))
if (!this._isLaunchable(app.origin))
continue;
aData.apps.push(app);

View File

@ -15,12 +15,6 @@ DIRS = src
ifdef ENABLE_TESTS
XPCSHELL_TESTS = tests/unit
ABS_topsrcdir = $(call core_abspath,$(topsrcdir))
libs::
$(NSINSTALL) -D $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/tests/unit/data
cd $(srcdir)/tests; $(PYTHON) $(ABS_topsrcdir)/config/nsinstall.py \
./ \
$(call core_abspath,$(DEPTH)/_tests/xpcshell/$(relativesrcdir)/tests/unit/data/)
endif
include $(topsrcdir)/config/rules.mk

Some files were not shown because too many files have changed in this diff Show More