diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2014-10-07 08:03:58 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2014-10-07 08:03:58 +0100 |
commit | 85aba4961a533bfb3f26314d854de19b781093ac (patch) | |
tree | d4de40fdc986c9304d2620b89012c1ee31395bde | |
parent | 48089ccf4f1f239b3268b2cb52b8aa0f7356485b (diff) | |
parent | 6ecf19c61221bddf5df3ee54f24daa90c91bdd71 (diff) | |
download | haskell-85aba4961a533bfb3f26314d854de19b781093ac.tar.gz |
Merge branch 'master' of http://git.haskell.org/ghc
29 files changed, 475 insertions, 224 deletions
diff --git a/.gitignore b/.gitignore index d578d5c945..19b55b20ee 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,7 @@ _darcs/ /ghc/ghc-bin.cabal /includes/ghcautoconf.h /includes/ghcplatform.h +/includes/ghcversion.h /index.html /inplace/ /libffi/build/ diff --git a/aclocal.m4 b/aclocal.m4 index 62cf6fe4e9..0db231db04 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1604,6 +1604,13 @@ AC_SUBST([ProjectVersionInt]) # The project patchlevel is zero unless stated otherwise test -z "$ProjectPatchLevel" && ProjectPatchLevel=0 +# Save split version of ProjectPatchLevel +ProjectPatchLevel1=`echo $ProjectPatchLevel | sed 's/^\(@<:@^.@:>@*\)\(\.\{0,1\}\(.*\)\)$/\1/'` +ProjectPatchLevel2=`echo $ProjectPatchLevel | sed 's/^\(@<:@^.@:>@*\)\(\.\{0,1\}\(.*\)\)$/\3/'` + +AC_SUBST([ProjectPatchLevel1]) +AC_SUBST([ProjectPatchLevel2]) + # Remove dots from the patch level; this allows us to have versions like 6.4.1.20050508 ProjectPatchLevel=`echo $ProjectPatchLevel | sed 's/\.//'` @@ -2208,4 +2215,53 @@ $2=$HS_CPP_ARGS ]) +# FP_BFD_SUPPORT() +# ---------------------- +# whether to use libbfd for debugging RTS +AC_DEFUN([FP_BFD_SUPPORT], [ + AC_ARG_ENABLE(bfd-debug, + [AC_HELP_STRING([--enable-bfd-debug], + [Enable symbol resolution for -debug rts ('+RTS -Di') via binutils' libbfd [default=no]])], + [ + # don't pollute general LIBS environment + save_LIBS="$LIBS" + AC_CHECK_HEADERS([bfd.h]) + dnl ** check whether this machine has BFD and libiberty installed (used for debugging) + dnl the order of these tests matters: bfd needs libiberty + AC_CHECK_LIB(iberty, xmalloc) + dnl 'bfd_init' is a rare non-macro in libbfd + AC_CHECK_LIB(bfd, bfd_init) + + AC_TRY_LINK([#include <bfd.h>], + [ + /* mimic our rts/Printer.c */ + bfd* abfd; + const char * name; + char **matching; + + name = "some.executable"; + bfd_init(); + abfd = bfd_openr(name, "default"); + bfd_check_format_matches (abfd, bfd_object, &matching); + { + long storage_needed; + storage_needed = bfd_get_symtab_upper_bound (abfd); + } + { + asymbol **symbol_table; + long number_of_symbols; + symbol_info info; + + number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); + bfd_get_symbol_info(abfd,symbol_table[0],&info); + } + ], + [],dnl bfd seems to work + [AC_MSG_ERROR([can't use 'bfd' library])]) + LIBS="$save_LIBS" + ], + [] + ) +]) + # LocalWords: fi diff --git a/compiler/ghc.mk b/compiler/ghc.mk index 05c935f889..0f9896066d 100644 --- a/compiler/ghc.mk +++ b/compiler/ghc.mk @@ -71,6 +71,10 @@ compiler/stage%/build/Config.hs : mk/config.mk mk/project.mk | $$(dir $$@)/. @echo 'cProjectVersionInt = "$(ProjectVersionInt)"' >> $@ @echo 'cProjectPatchLevel :: String' >> $@ @echo 'cProjectPatchLevel = "$(ProjectPatchLevel)"' >> $@ + @echo 'cProjectPatchLevel1 :: String' >> $@ + @echo 'cProjectPatchLevel1 = "$(ProjectPatchLevel1)"' >> $@ + @echo 'cProjectPatchLevel2 :: String' >> $@ + @echo 'cProjectPatchLevel2 = "$(ProjectPatchLevel2)"' >> $@ @echo 'cBooterVersion :: String' >> $@ @echo 'cBooterVersion = "$(GhcVersion)"' >> $@ @echo 'cStage :: String' >> $@ @@ -467,36 +471,15 @@ compiler_stage2_dll0_MODULES = \ BasicTypes \ BinIface \ Binary \ - Bitmap \ - BlockId \ BooleanFormula \ BreakArray \ BufWrite \ BuildTyCl \ - ByteCodeAsm \ - ByteCodeInstr \ - ByteCodeItbls \ - CLabel \ Class \ CmdLineParser \ - Cmm \ - CmmCallConv \ - CmmExpr \ - CmmInfo \ - CmmMachOp \ - CmmNode \ CmmType \ - CmmUtils \ CoAxiom \ ConLike \ - CodeGen.Platform \ - CodeGen.Platform.ARM \ - CodeGen.Platform.NoRegs \ - CodeGen.Platform.PPC \ - CodeGen.Platform.PPC_Darwin \ - CodeGen.Platform.SPARC \ - CodeGen.Platform.X86 \ - CodeGen.Platform.X86_64 \ Coercion \ Config \ Constants \ @@ -520,7 +503,6 @@ compiler_stage2_dll0_MODULES = \ Exception \ ExtsCompat46 \ FamInstEnv \ - FastBool \ FastFunctions \ FastMutInt \ FastString \ @@ -530,8 +512,6 @@ compiler_stage2_dll0_MODULES = \ FiniteMap \ ForeignCall \ Hooks \ - Hoopl \ - Hoopl.Dataflow \ HsBinds \ HsDecls \ HsDoc \ @@ -551,14 +531,12 @@ compiler_stage2_dll0_MODULES = \ IfaceSyn \ IfaceType \ InstEnv \ - InteractiveEvalTypes \ Kind \ ListSetOps \ Literal \ LoadIface \ Maybes \ MkCore \ - MkGraph \ MkId \ Module \ MonadUtils \ @@ -578,9 +556,6 @@ compiler_stage2_dll0_MODULES = \ PipelineMonad \ Platform \ PlatformConstants \ - PprCmm \ - PprCmmDecl \ - PprCmmExpr \ PprCore \ PrelInfo \ PrelNames \ @@ -588,23 +563,10 @@ compiler_stage2_dll0_MODULES = \ Pretty \ PrimOp \ RdrName \ - Reg \ - RegClass \ Rules \ - SMRep \ Serialized \ SrcLoc \ StaticFlags \ - StgCmmArgRep \ - StgCmmClosure \ - StgCmmEnv \ - StgCmmLayout \ - StgCmmMonad \ - StgCmmProf \ - StgCmmTicky \ - StgCmmUtils \ - StgSyn \ - Stream \ StringBuffer \ TcEvidence \ TcIface \ @@ -628,6 +590,54 @@ compiler_stage2_dll0_MODULES = \ VarEnv \ VarSet +ifeq "$(GhcWithInterpreter)" "YES" +# These files are reacheable from DynFlags +# only by GHCi-enabled code (see #9552) +compiler_stage2_dll0_MODULES += \ + Bitmap \ + BlockId \ + ByteCodeAsm \ + ByteCodeInstr \ + ByteCodeItbls \ + CLabel \ + Cmm \ + CmmCallConv \ + CmmExpr \ + CmmInfo \ + CmmMachOp \ + CmmNode \ + CmmUtils \ + CodeGen.Platform \ + CodeGen.Platform.ARM \ + CodeGen.Platform.NoRegs \ + CodeGen.Platform.PPC \ + CodeGen.Platform.PPC_Darwin \ + CodeGen.Platform.SPARC \ + CodeGen.Platform.X86 \ + CodeGen.Platform.X86_64 \ + FastBool \ + Hoopl \ + Hoopl.Dataflow \ + InteractiveEvalTypes \ + MkGraph \ + PprCmm \ + PprCmmDecl \ + PprCmmExpr \ + Reg \ + RegClass \ + SMRep \ + StgCmmArgRep \ + StgCmmClosure \ + StgCmmEnv \ + StgCmmLayout \ + StgCmmMonad \ + StgCmmProf \ + StgCmmTicky \ + StgCmmUtils \ + StgSyn \ + Stream +endif + compiler_stage2_dll0_HS_OBJS = \ $(patsubst %,compiler/stage2/build/%.$(dyn_osuf),$(subst .,/,$(compiler_stage2_dll0_MODULES))) diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs index ca720070c0..562c7d74be 100644 --- a/compiler/main/DriverPipeline.hs +++ b/compiler/main/DriverPipeline.hs @@ -1089,6 +1089,8 @@ runPhase (RealPhase cc_phase) input_fn dflags -- very weakly typed, being derived from C--. ["-fno-strict-aliasing"] + ghcVersionH <- liftIO $ getGhcVersionPathName dflags + let gcc_lang_opt | cc_phase `eqPhase` Ccpp = "c++" | cc_phase `eqPhase` Cobjc = "objective-c" | cc_phase `eqPhase` Cobjcpp = "objective-c++" @@ -1138,7 +1140,9 @@ runPhase (RealPhase cc_phase) input_fn dflags ++ verbFlags ++ [ "-S" ] ++ cc_opt - ++ [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt ] + ++ [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt + , "-include", ghcVersionH + ] ++ framework_paths ++ split_opt ++ include_paths @@ -2092,6 +2096,13 @@ doCpp dflags raw input_fn output_fn = do backend_defs <- getBackendDefs dflags + -- Default CPP defines in Haskell source + ghcVersionH <- getGhcVersionPathName dflags + let hsSourceCppOpts = + [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt + , "-include", ghcVersionH + ] + cpp_prog ( map SysTools.Option verbFlags ++ map SysTools.Option include_paths ++ map SysTools.Option hsSourceCppOpts @@ -2129,11 +2140,6 @@ getBackendDefs dflags | hscTarget dflags == HscLlvm = do getBackendDefs _ = return [] -hsSourceCppOpts :: [String] --- Default CPP defines in Haskell source -hsSourceCppOpts = - [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt ] - -- --------------------------------------------------------------------------- -- join object files into a single relocatable object file, using ld -r @@ -2213,6 +2219,16 @@ haveRtsOptsFlags dflags = RtsOptsSafeOnly -> False _ -> True +-- | Find out path to @ghcversion.h@ file +getGhcVersionPathName :: DynFlags -> IO FilePath +getGhcVersionPathName dflags = do + dirs <- getPackageIncludePath dflags [rtsPackageKey] + + found <- filterM doesFileExist (map (</> "ghcversion.h") dirs) + case found of + [] -> throwGhcExceptionIO (InstallationError ("ghcversion.h missing")) + (x:_) -> return x + -- Note [-fPIC for assembler] -- When compiling .c source file GHC's driver pipeline basically -- does the following two things: diff --git a/configure.ac b/configure.ac index e7a07744f3..7b59f78c00 100644 --- a/configure.ac +++ b/configure.ac @@ -753,7 +753,7 @@ dnl off_t, because it will affect the result of that test. AC_SYS_LARGEFILE dnl ** check for specific header (.h) files that we are interested in -AC_CHECK_HEADERS([bfd.h ctype.h dirent.h dlfcn.h errno.h fcntl.h grp.h limits.h locale.h nlist.h pthread.h pwd.h signal.h sys/param.h sys/mman.h sys/resource.h sys/select.h sys/time.h sys/timeb.h sys/timers.h sys/times.h sys/utsname.h sys/wait.h termios.h time.h utime.h windows.h winsock.h sched.h]) +AC_CHECK_HEADERS([ctype.h dirent.h dlfcn.h errno.h fcntl.h grp.h limits.h locale.h nlist.h pthread.h pwd.h signal.h sys/param.h sys/mman.h sys/resource.h sys/select.h sys/time.h sys/timeb.h sys/timers.h sys/times.h sys/utsname.h sys/wait.h termios.h time.h utime.h windows.h winsock.h sched.h]) dnl sys/cpuset.h needs sys/param.h to be included first on FreeBSD 9.1; #7708 AC_CHECK_HEADERS([sys/cpuset.h], [], [], @@ -846,10 +846,7 @@ then AC_DEFINE([HAVE_LIBM], [1], [Define to 1 if you need to link with libm]) fi -dnl ** check whether this machine has BFD and libiberty installed (used for debugging) -dnl the order of these tests matters: bfd needs libiberty -AC_CHECK_LIB(iberty, xmalloc) -AC_CHECK_LIB(bfd, bfd_uncompress_section_contents) +FP_BFD_SUPPORT dnl ################################################################ dnl Check for libraries diff --git a/docs/users_guide/phases.xml b/docs/users_guide/phases.xml index 095de32516..085ebbf509 100644 --- a/docs/users_guide/phases.xml +++ b/docs/users_guide/phases.xml @@ -389,6 +389,85 @@ $ cat foo.hspp</screen> <varlistentry> <term> + <constant>__GLASGOW_HASKELL_PATCHLEVEL1__</constant> + <indexterm><primary><constant>__GLASGOW_HASKELL_PATCHLEVEL1__</constant></primary></indexterm> + </term> + <term> + <constant>__GLASGOW_HASKELL_PATCHLEVEL2__</constant> + <indexterm><primary><constant>__GLASGOW_HASKELL_PATCHLEVEL2__</constant></primary></indexterm> + </term> + <listitem> + <para>These macros are available starting with GHC 7.10.1.</para> + + <para>For three-part GHC version numbers + <literal><replaceable>x</replaceable>.<replaceable>y</replaceable>.<replaceable>z</replaceable></literal>, + the value of + <constant>__GLASGOW_HASKELL_PATCHLEVEL1__</constant> + is the integer <replaceable>z</replaceable>.</para> + + <para>For four-part GHC version numbers + <literal><replaceable>x</replaceable>.<replaceable>y</replaceable>.<replaceable>z</replaceable>.<replaceable>z'</replaceable></literal>, + the value of + <constant>__GLASGOW_HASKELL_PATCHLEVEL1__</constant> + is the integer <replaceable>z</replaceable> while the value of + <constant>__GLASGOW_HASKELL_PATCHLEVEL2__</constant> + is set to the integer <replaceable>z'</replaceable>.</para> + + <para>These macros are provided for allowing finer + granularity than is provided by + <literal>__GLASGOW_HASKELL__</literal>. Usually, this should + not be necessary as it's expected for most APIs to remain + stable between patchlevel releases, but occasionally + internal API changes are necessary to fix bugs. Also + conditional compilation on the patchlevel can be useful for + working around bugs in older releases.</para> + + <para>NB. These macros are set when pre-processing both + Haskell source and C source, including the C source + generated from a Haskell module + (i.e. <filename>.hs</filename>, <filename>.lhs</filename>, + <filename>.c</filename> and <filename>.hc</filename> + files).</para> + </listitem> + </varlistentry> + + <varlistentry> + <term> + <constant>MIN_VERSION_GLASGOW_HASKELL(<replaceable>x</replaceable>,<replaceable>y</replaceable>,<replaceable>z</replaceable>,<replaceable>z'</replaceable>)</constant> + <indexterm><primary><constant>MIN_VERSION_GLASGOW_HASKELL</constant></primary></indexterm> + </term> + <listitem> + <para>This macro is available starting with GHC 7.10.1.</para> + + <para>This macro is provided for convenience to write CPP + conditionals testing whether the GHC version used is version + <literal><replaceable>x</replaceable>.<replaceable>y</replaceable>.<replaceable>z</replaceable>.<replaceable>z'</replaceable></literal> + or later.</para> + + <para>If compatibility with Haskell compilers (including GHC + prior to version 7.10.1) which do not define + <literal>MIN_VERSION_GLASGOW_HASKELL</literal> is required, + the presence of the + <literal>MIN_VERSION_GLASGOW_HASKELL</literal> macro needs + to be ensured before it is called, e.g.:</para> + +<programlisting>#ifdef MIN_VERSION_GLASGOW_HASKELL +#if MIN_VERSION_GLASGOW_HASKELL(7,10,2,0) +/* code that applies only to GHC 7.10.2 or later */ +#endif +#endif</programlisting> + + <para>NB. This macro is set when pre-processing both + Haskell source and C source, including the C source + generated from a Haskell module + (i.e. <filename>.hs</filename>, <filename>.lhs</filename>, + <filename>.c</filename> and <filename>.hc</filename> + files).</para> + </listitem> + </varlistentry> + + <varlistentry> + <term> <constant>__GLASGOW_HASKELL_LLVM__</constant> <indexterm><primary><constant>__GLASGOW_HASKELL_LLVM__</constant></primary></indexterm> </term> @@ -1223,6 +1223,7 @@ CLEAN_FILES += includes/GHCConstants.h CLEAN_FILES += includes/DerivedConstants.h CLEAN_FILES += includes/ghcautoconf.h CLEAN_FILES += includes/ghcplatform.h +CLEAN_FILES += includes/ghcversion.h CLEAN_FILES += utils/ghc-pkg/Version.hs CLEAN_FILES += compiler/parser/Parser.y CLEAN_FILES += compiler/prelude/primops.txt diff --git a/includes/ghc.mk b/includes/ghc.mk index 5342cc8c02..f0bfbec0da 100644 --- a/includes/ghc.mk +++ b/includes/ghc.mk @@ -16,6 +16,7 @@ # XXX: these should go in includes/dist/build? includes_H_CONFIG = includes/ghcautoconf.h includes_H_PLATFORM = includes/ghcplatform.h +includes_H_VERSION = includes/ghcversion.h # # All header files are in includes/{one of these subdirectories} @@ -53,6 +54,34 @@ ifeq "$(DYNAMIC_BY_DEFAULT)" "YES" includes_CC_OPTS += -DDYNAMIC_BY_DEFAULT endif + +$(includes_H_VERSION) : mk/project.mk | $$(dir $$@)/. + @echo "Creating $@..." + @echo "#ifndef __GHCVERSION_H__" > $@ + @echo "#define __GHCVERSION_H__" >> $@ + @echo >> $@ + @echo "#ifndef __GLASGOW_HASKELL__" >> $@ + @echo "# define __GLASGOW_HASKELL__ $(ProjectVersionInt)" >> $@ + @echo "#endif" >> $@ + @echo >> $@ + @if [ -n "$(ProjectPatchLevel1)" ]; then \ + echo "#define __GLASGOW_HASKELL_PATCHLEVEL1__ $(ProjectPatchLevel1)" >> $@; \ + fi + @if [ -n "$(ProjectPatchLevel2)" ]; then \ + echo "#define __GLASGOW_HASKELL_PATCHLEVEL1__ $(ProjectPatchLevel2)" >> $@; \ + fi + @echo >> $@ + @echo '#define MIN_VERSION_GLASGOW_HASKELL(ma,mi,pl1,pl2) (\\' >> $@ + @echo ' ((ma)*100+(mi)) < __GLASGOW_HASKELL__ || \\' >> $@ + @echo ' ((ma)*100+(mi)) == __GLASGOW_HASKELL__ \\' >> $@ + @echo ' && (pl1) < __GLASGOW_HASKELL_PATCHLEVEL1__ || \\'>> $@ + @echo ' ((ma)*100+(mi)) == __GLASGOW_HASKELL__ \\' >> $@ + @echo ' && (pl1) == __GLASGOW_HASKELL_PATCHLEVEL1__ \\' >> $@ + @echo ' && (pl2) <= __GLASGOW_HASKELL_PATCHLEVEL2__ )' >> $@ + @echo >> $@ + @echo "#endif /* __GHCVERSION_H__ */" >> $@ + @echo "Done." + ifneq "$(BINDIST)" "YES" ifeq "$(PORTING_HOST)" "YES" @@ -160,8 +189,8 @@ DERIVE_CONSTANTS_FLAGS += $(addprefix --gcc-flag$(space),$(includes_CC_OPTS) -fc DERIVE_CONSTANTS_FLAGS += --nm-program "$(NM)" ifneq "$(BINDIST)" "YES" -$(includes_DERIVEDCONSTANTS): $$(includes_H_CONFIG) $$(includes_H_PLATFORM) $$(includes_H_FILES) $$(rts_H_FILES) -$(includes_GHCCONSTANTS_HASKELL_VALUE): $$(includes_H_CONFIG) $$(includes_H_PLATFORM) $$(includes_H_FILES) $$(rts_H_FILES) +$(includes_DERIVEDCONSTANTS): $$(includes_H_CONFIG) $$(includes_H_PLATFORM) $$(includes_H_VERSION) $$(includes_H_FILES) $$(rts_H_FILES) +$(includes_GHCCONSTANTS_HASKELL_VALUE): $$(includes_H_CONFIG) $$(includes_H_PLATFORM) $$(includes_H_VERSION) $$(includes_H_FILES) $$(rts_H_FILES) $(includes_DERIVEDCONSTANTS): $(deriveConstants_INPLACE) | $$(dir $$@)/. $< --gen-header -o $@ --tmpdir $(dir $@) $(DERIVE_CONSTANTS_FLAGS) @@ -183,10 +212,10 @@ endif # Install all header files $(eval $(call clean-target,includes,,\ - $(includes_H_CONFIG) $(includes_H_PLATFORM))) + $(includes_H_CONFIG) $(includes_H_PLATFORM) $(includes_H_VERSION))) $(eval $(call all-target,includes,\ - $(includes_H_CONFIG) $(includes_H_PLATFORM) \ + $(includes_H_CONFIG) $(includes_H_PLATFORM) $(includes_H_VERSION) \ $(includes_GHCCONSTANTS_HASKELL_TYPE) \ $(includes_GHCCONSTANTS_HASKELL_VALUE) \ $(includes_GHCCONSTANTS_HASKELL_WRAPPERS) \ @@ -202,5 +231,5 @@ install_includes : $(call INSTALL_DIR,"$(DESTDIR)$(ghcheaderdir)/$d") && \ $(call INSTALL_HEADER,$(INSTALL_OPTS),includes/$d/*.h,"$(DESTDIR)$(ghcheaderdir)/$d/") && \ ) true - $(call INSTALL_HEADER,$(INSTALL_OPTS),$(includes_H_CONFIG) $(includes_H_PLATFORM) $(includes_DERIVEDCONSTANTS),"$(DESTDIR)$(ghcheaderdir)/") + $(call INSTALL_HEADER,$(INSTALL_OPTS),$(includes_H_CONFIG) $(includes_H_PLATFORM) $(includes_H_VERSION) $(includes_DERIVEDCONSTANTS),"$(DESTDIR)$(ghcheaderdir)/") diff --git a/libraries/base/Data/Proxy.hs b/libraries/base/Data/Proxy.hs index 38a43b0b0f..3ead549daf 100644 --- a/libraries/base/Data/Proxy.hs +++ b/libraries/base/Data/Proxy.hs @@ -34,6 +34,10 @@ data Proxy t = Proxy -- There are no instances for this because it is intended at the kind level only data KProxy (t :: *) = KProxy +-- It's common to use (undefined :: Proxy t) and (Proxy :: Proxy t) +-- interchangeably, so all of these instances are hand-written to be +-- lazy in Proxy arguments. + instance Eq (Proxy s) where _ == _ = True diff --git a/mk/project.mk.in b/mk/project.mk.in index 69ed88575e..129b540c88 100644 --- a/mk/project.mk.in +++ b/mk/project.mk.in @@ -29,6 +29,8 @@ ProjectTags = ProjectVersion = @ProjectVersion@$(ProjectTags) ProjectVersionInt = @ProjectVersionInt@ ProjectPatchLevel = @ProjectPatchLevel@ +ProjectPatchLevel1 = @ProjectPatchLevel1@ +ProjectPatchLevel2 = @ProjectPatchLevel2@ ################################################################################ # diff --git a/rts/Linker.c b/rts/Linker.c index 9897557530..e74d647283 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -4163,6 +4163,7 @@ ocGetNames_PEi386 ( ObjectCode* oc ) 0==strcmp(".rodata",(char*)secname)) kind = SECTIONKIND_CODE_OR_RODATA; if (0==strcmp(".data",(char*)secname) || + 0==strcmp("staticclosures",(char*)secname) || 0==strcmp(".bss",(char*)secname)) kind = SECTIONKIND_RWDATA; if (0==strcmp(".ctors", (char*)secname)) diff --git a/rts/Printer.c b/rts/Printer.c index 3d77e83282..9bc2984384 100644 --- a/rts/Printer.c +++ b/rts/Printer.c @@ -7,6 +7,8 @@ * ---------------------------------------------------------------------------*/ #include "PosixSource.h" +#include "ghcconfig.h" + #include "Rts.h" #include "rts/Bytecodes.h" /* for InstrPtr */ @@ -664,8 +666,16 @@ const char *lookupGHCName( void *addr ) disabling this for now. */ #ifdef USING_LIBBFD - -#include <bfd.h> +# define PACKAGE 1 +# define PACKAGE_VERSION 1 +/* Those PACKAGE_* defines are workarounds for bfd: + * https://sourceware.org/bugzilla/show_bug.cgi?id=14243 + * ghc's build system filter PACKAGE_* values out specifically to avoid clashes + * with user's autoconf-based Cabal packages. + * It's a shame <bfd.h> checks for unrelated fields instead of actually used + * macros. + */ +# include <bfd.h> /* Fairly ad-hoc piece of code that seems to filter out a lot of * rubbish like the obj-splitting symbols @@ -733,7 +743,6 @@ extern void DEBUG_LoadSymbols( char *name ) for( i = 0; i != number_of_symbols; ++i ) { symbol_info info; bfd_get_symbol_info(abfd,symbol_table[i],&info); - /*debugBelch("\t%c\t0x%x \t%s\n",info.type,(nat)info.value,info.name); */ if (isReal(info.type, info.name)) { num_real_syms += 1; } diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c index 98a43c0586..5e6f9fab54 100644 --- a/rts/RtsStartup.c +++ b/rts/RtsStartup.c @@ -19,6 +19,7 @@ #include "RtsFlags.h" #include "RtsUtils.h" #include "Prelude.h" +#include "Printer.h" /* DEBUG_LoadSymbols */ #include "Schedule.h" /* initScheduler */ #include "Stats.h" /* initStats */ #include "STM.h" /* initSTM */ @@ -162,6 +163,11 @@ hs_init_ghc(int *argc, char **argv[], RtsConfig rts_config) rts_config.rts_opts_enabled, rts_config.rts_opts, rts_config.rts_hs_main); } +#ifdef DEBUG + /* load debugging symbols for current binary */ + DEBUG_LoadSymbols((*argv)[0]); +#endif /* DEBUG */ + /* Initialise the stats department, phase 1 */ initStats1(); diff --git a/testsuite/config/ghc b/testsuite/config/ghc index 84b89d49bb..031d955552 100644 --- a/testsuite/config/ghc +++ b/testsuite/config/ghc @@ -148,17 +148,21 @@ config.way_rts_flags = { # Useful classes of ways that can be used with only_ways() and # expect_broken_for(). -prof_ways = [x[0] for x in config.way_flags('dummy_name').items() - if '-prof' in x[1]] +prof_ways = map (lambda x: x[0], \ + filter(lambda x: '-prof' in x[1], \ + config.way_flags('dummy_name').items())) -threaded_ways = [x[0] for x in config.way_flags('dummy_name').items() - if '-threaded' in x[1] or 'ghci' == x[0]] +threaded_ways = map (lambda x: x[0], \ + filter(lambda x: '-threaded' in x[1] or 'ghci' == x[0], \ + config.way_flags('dummy_name').items())) -opt_ways = [x[0] for x in config.way_flags('dummy_name').items() - if '-O' in x[1]] +opt_ways = map (lambda x: x[0], \ + filter(lambda x: '-O' in x[1], \ + config.way_flags('dummy_name').items())) -llvm_ways = [x[0] for x in config.way_flags('dummy_name').items() - if '-fflvm' in x[1]] +llvm_ways = map (lambda x: x[0], \ + filter(lambda x: '-fllvm' in x[1], \ + config.way_flags('dummy_name').items())) def get_compiler_info(): # This should really not go through the shell @@ -188,7 +192,7 @@ def get_compiler_info(): if re.match(".*_p(_.*|$)", rtsInfoDict["RTS way"]): config.compiler_profiled = True - config.run_ways = [x for x in config.run_ways if x != 'ghci'] + config.run_ways = filter(lambda x: x != 'ghci', config.run_ways) else: config.compiler_profiled = False diff --git a/testsuite/driver/runtests.py b/testsuite/driver/runtests.py index 883bda754e..103c7ace7c 100644 --- a/testsuite/driver/runtests.py +++ b/testsuite/driver/runtests.py @@ -2,8 +2,6 @@ # (c) Simon Marlow 2002 # -from __future__ import print_function - import sys import os import string @@ -23,11 +21,6 @@ try: except: pass -PYTHON3 = sys.version_info >= (3, 0) -if PYTHON3: - print("*** WARNING: running testsuite using Python 3.\n" - "*** Python 3 support is experimental. See Trac #9184.") - from testutil import * from testglobals import * @@ -59,12 +52,12 @@ opts, args = getopt.getopt(sys.argv[1:], "e:", long_options) for opt,arg in opts: if opt == '--config': - exec(open(arg).read()) + execfile(arg) # -e is a string to execute from the command line. For example: # testframe -e 'config.compiler=ghc-5.04' if opt == '-e': - exec(arg) + exec arg if opt == '--rootdir': config.rootdirs.append(arg) @@ -90,9 +83,9 @@ for opt,arg in opts: sys.stderr.write("ERROR: requested way \'" + arg + "\' does not exist\n") sys.exit(1) - config.other_ways = [w for w in config.other_ways if w != arg] - config.run_ways = [w for w in config.run_ways if w != arg] - config.compile_ways = [w for w in config.compile_ways if w != arg] + config.other_ways = filter(neq(arg), config.other_ways) + config.run_ways = filter(neq(arg), config.run_ways) + config.compile_ways = filter(neq(arg), config.compile_ways) if opt == '--threads': config.threads = int(arg) @@ -124,17 +117,17 @@ if config.use_threads == 1: maj = int(re.sub('[^0-9].*', '', str(maj))) min = int(re.sub('[^0-9].*', '', str(min))) pat = int(re.sub('[^0-9].*', '', str(pat))) - if (maj, min) < (2, 6): - print("Python < 2.6 is not supported") - sys.exit(1) + if (maj, min, pat) < (2, 5, 2): + print "Warning: Ignoring request to use threads as python version < 2.5.2" + config.use_threads = 0 # We also need to disable threads for python 2.7.2, because of # this bug: http://bugs.python.org/issue13817 elif (maj, min, pat) == (2, 7, 2): - print("Warning: Ignoring request to use threads as python version is 2.7.2") - print("See http://bugs.python.org/issue13817 for details.") + print "Warning: Ignoring request to use threads as python version is 2.7.2" + print "See http://bugs.python.org/issue13817 for details." config.use_threads = 0 if windows: - print("Warning: Ignoring request to use threads as running on Windows") + print "Warning: Ignoring request to use threads as running on Windows" config.use_threads = 0 config.cygwin = False @@ -189,10 +182,10 @@ else: h.close() if v != '': os.environ['LC_ALL'] = v - print("setting LC_ALL to", v) + print "setting LC_ALL to", v else: - print('WARNING: No UTF8 locale found.') - print('You may get some spurious test failures.') + print 'WARNING: No UTF8 locale found.' + print 'You may get some spurious test failures.' # This has to come after arg parsing as the args can change the compiler get_compiler_info() @@ -239,7 +232,7 @@ if config.use_threads: if config.timeout == -1: config.timeout = int(read_no_crs(config.top + '/timeout/calibrate.out')) -print('Timeout is ' + str(config.timeout)) +print 'Timeout is ' + str(config.timeout) # ----------------------------------------------------------------------------- # The main dude @@ -249,44 +242,40 @@ if config.rootdirs == []: t_files = findTFiles(config.rootdirs) -print('Found', len(t_files), '.T files...') +print 'Found', len(t_files), '.T files...' t = getTestRun() # Avoid cmd.exe built-in 'date' command on Windows t.start_time = time.localtime() -print('Beginning test run at', time.strftime("%c %Z",t.start_time)) +print 'Beginning test run at', time.strftime("%c %Z",t.start_time) +# set stdout to unbuffered (is this the best way to do it?) sys.stdout.flush() -if PYTHON3: - # in Python 3, we output text, which cannot be unbuffered - sys.stdout = os.fdopen(sys.__stdout__.fileno(), "w") -else: - # set stdout to unbuffered (is this the best way to do it?) - sys.stdout = os.fdopen(sys.__stdout__.fileno(), "w", 0) +sys.stdout = os.fdopen(sys.__stdout__.fileno(), "w", 0) # First collect all the tests to be run for file in t_files: if_verbose(2, '====> Scanning %s' % file) newTestDir(os.path.dirname(file)) try: - exec(open(file).read()) - except Exception: - print('*** framework failure: found an error while executing ', file, ':') + execfile(file) + except: + print '*** framework failure: found an error while executing ', file, ':' t.n_framework_failures = t.n_framework_failures + 1 traceback.print_exc() if config.list_broken: global brokens - print('') - print('Broken tests:') - print(' '.join(map (lambda bdn: '#' + str(bdn[0]) + '(' + bdn[1] + '/' + bdn[2] + ')', brokens))) - print('') + print '' + print 'Broken tests:' + print (' '.join(map (lambda (b, d, n) : '#' + str(b) + '(' + d + '/' + n + ')', brokens))) + print '' if t.n_framework_failures != 0: - print('WARNING:', str(t.n_framework_failures), 'framework failures!') - print('') + print 'WARNING:', str(t.n_framework_failures), 'framework failures!' + print '' else: # Now run all the tests if config.use_threads: diff --git a/testsuite/driver/testlib.py b/testsuite/driver/testlib.py index 2e79476df8..e3562f7c54 100644 --- a/testsuite/driver/testlib.py +++ b/testsuite/driver/testlib.py @@ -2,7 +2,8 @@ # (c) Simon Marlow 2002 # -from __future__ import print_function +# This allows us to use the "with X:" syntax with python 2.5: +from __future__ import with_statement import shutil import sys @@ -15,6 +16,7 @@ import time import datetime import copy import glob +import types from math import ceil, trunc have_subprocess = False @@ -22,17 +24,15 @@ try: import subprocess have_subprocess = True except: - print("Warning: subprocess not found, will fall back to spawnv") + print "Warning: subprocess not found, will fall back to spawnv" +from string import join from testglobals import * from testutil import * if config.use_threads: import threading - try: - import thread - except ImportError: # Python 3 - import _thread as thread + import thread global wantToStop wantToStop = False @@ -99,7 +99,7 @@ def reqlib( lib ): have_lib = {} def _reqlib( name, opts, lib ): - if lib in have_lib: + if have_lib.has_key(lib): got_it = have_lib[lib] else: if have_subprocess: @@ -284,7 +284,7 @@ def _stats_num_field( name, opts, field, expecteds ): if field in opts.stats_range_fields: framework_fail(name, 'duplicate-numfield', 'Duplicate ' + field + ' num_field check') - if type(expecteds) is list: + if type(expecteds) is types.ListType: for (b, expected, dev) in expecteds: if b: opts.stats_range_fields[field] = (expected, dev) @@ -512,10 +512,9 @@ def two_normalisers(f, g): # Function for composing two opt-fns together def executeSetups(fs, name, opts): - if type(fs) is list: + if type(fs) is types.ListType: # If we have a list of setups, then execute each one - for f in fs: - executeSetups(f, name, opts) + map (lambda f : executeSetups(f, name, opts), fs) else: # fs is a single function, so just apply it fs(name, opts) @@ -626,7 +625,8 @@ def test_common_work (name, opts, func, args): all_ways = ['normal'] # A test itself can request extra ways by setting opts.extra_ways - all_ways = all_ways + [way for way in opts.extra_ways if way not in all_ways] + all_ways = all_ways + filter(lambda way: way not in all_ways, + opts.extra_ways) t.total_test_cases = t.total_test_cases + len(all_ways) @@ -639,7 +639,7 @@ def test_common_work (name, opts, func, args): and way not in getTestOpts().omit_ways # Which ways we are asked to skip - do_ways = list(filter (ok_way,all_ways)) + do_ways = filter (ok_way,all_ways) # In fast mode, we skip all but one way if config.fast and len(do_ways) > 0: @@ -658,8 +658,8 @@ def test_common_work (name, opts, func, args): if getTestOpts().cleanup != '' and (config.clean_only or do_ways != []): pretest_cleanup(name) - clean([name + suff for suff in [ - '', '.exe', '.exe.manifest', '.genscript', + clean(map (lambda suff: name + suff, + ['', '.exe', '.exe.manifest', '.genscript', '.stderr.normalised', '.stdout.normalised', '.run.stderr.normalised', '.run.stdout.normalised', '.comp.stderr.normalised', '.comp.stdout.normalised', @@ -667,13 +667,12 @@ def test_common_work (name, opts, func, args): '.stats', '.comp.stats', '.hi', '.o', '.prof', '.exe.prof', '.hc', '_stub.h', '_stub.c', '_stub.o', - '.hp', '.exe.hp', '.ps', '.aux', '.hcr', '.eventlog']]) + '.hp', '.exe.hp', '.ps', '.aux', '.hcr', '.eventlog'])) if func == multi_compile or func == multi_compile_fail: extra_mods = args[1] - clean([replace_suffix(fx[0],'o') for fx in extra_mods]) - clean([replace_suffix(fx[0], 'hi') for fx in extra_mods]) - + clean(map (lambda (f,x): replace_suffix(f, 'o'), extra_mods)) + clean(map (lambda (f,x): replace_suffix(f, 'hi'), extra_mods)) clean(getTestOpts().clean_files) @@ -713,7 +712,7 @@ def test_common_work (name, opts, func, args): files_written_not_removed[name] = [f] except: pass - except Exception as e: + except Exception, e: framework_fail(name, 'runTest', 'Unhandled exception: ' + str(e)) def clean(strs): @@ -725,19 +724,19 @@ def clean_full_path(name): try: # Remove files... os.remove(name) - except OSError as e1: + except OSError, e1: try: # ... and empty directories os.rmdir(name) - except OSError as e2: + except OSError, e2: # We don't want to fail here, but we do want to know # what went wrong, so print out the exceptions. # ENOENT isn't a problem, though, as we clean files # that don't necessarily exist. if e1.errno != errno.ENOENT: - print(e1) + print e1 if e2.errno != errno.ENOENT: - print(e2) + print e2 def do_test(name, way, func, args): full_name = name + '(' + way + ')' @@ -762,7 +761,7 @@ def do_test(name, way, func, args): framework_fail(name, way, 'pre-command exception') try: - result = func(*[name,way] + args) + result = apply(func, [name,way] + args) finally: if config.use_threads: t.lock.acquire() @@ -893,8 +892,7 @@ def run_command( name, way, cmd ): def ghci_script( name, way, script ): # filter out -fforce-recomp from compiler_always_flags, because we're # actually testing the recompilation behaviour in the GHCi tests. - flags = [f for f in getTestOpts().compiler_always_flags if f != '-fforce-recomp'] - + flags = filter(lambda f: f != '-fforce-recomp', getTestOpts().compiler_always_flags) flags.append(getTestOpts().extra_hc_opts) if getTestOpts().outputdir != None: flags.extend(["-outputdir", getTestOpts().outputdir]) @@ -902,10 +900,10 @@ def ghci_script( name, way, script ): # We pass HC and HC_OPTS as environment variables, so that the # script can invoke the correct compiler by using ':! $HC $HC_OPTS' cmd = "HC='" + config.compiler + "' " + \ - "HC_OPTS='" + ' '.join(flags) + "' " + \ + "HC_OPTS='" + join(flags,' ') + "' " + \ "'" + config.compiler + "'" + \ ' --interactive -v0 -ignore-dot-ghci ' + \ - ' '.join(flags) + join(flags,' ') getTestOpts().stdin = script return simple_run( name, way, cmd, getTestOpts().extra_run_opts ) @@ -969,7 +967,7 @@ def do_compile( name, way, should_fail, top_mod, extra_mods, extra_hc_opts ): return passed() def compile_cmp_asm( name, way, extra_hc_opts ): - print('Compile only, extra args = ', extra_hc_opts) + print 'Compile only, extra args = ', extra_hc_opts pretest_cleanup(name) result = simple_build( name + '.cmm', way, '-keep-s-files -O ' + extra_hc_opts, 0, '', 0, 0, 0) @@ -1051,7 +1049,7 @@ def checkStats(name, way, stats_file, range_fields): for (field, (expected, dev)) in range_fields.items(): m = re.search('\("' + field + '", "([0-9]+)"\)', contents) if m == None: - print('Failed to find field: ', field) + print 'Failed to find field: ', field result = failBecause('no such stats field') val = int(m.group(1)) @@ -1061,12 +1059,12 @@ def checkStats(name, way, stats_file, range_fields): deviation = round(((float(val) * 100)/ expected) - 100, 1) if val < lowerBound: - print(field, 'value is too low:') - print('(If this is because you have improved GHC, please') - print('update the test so that GHC doesn\'t regress again)') + print field, 'value is too low:' + print '(If this is because you have improved GHC, please' + print 'update the test so that GHC doesn\'t regress again)' result = failBecause('stat too good') if val > upperBound: - print(field, 'value is too high:') + print field, 'value is too high:' result = failBecause('stat not good enough') if val < lowerBound or val > upperBound or config.verbose >= 4: @@ -1074,11 +1072,9 @@ def checkStats(name, way, stats_file, range_fields): valLen = len(valStr) expectedStr = str(expected) expectedLen = len(expectedStr) - length = max(len(str(x)) for x in [expected, lowerBound, upperBound, val]) - + length = max(map (lambda x : len(str(x)), [expected, lowerBound, upperBound, val])) def display(descr, val, extra): - print(descr, str(val).rjust(length), extra) - + print descr, string.rjust(str(val), length), extra display(' Expected ' + full_name + ' ' + field + ':', expected, '+/-' + str(dev) + '%') display(' Lower bound ' + full_name + ' ' + field + ':', lowerBound, '') display(' Upper bound ' + full_name + ' ' + field + ':', upperBound, '') @@ -1153,15 +1149,15 @@ def simple_build( name, way, extra_hc_opts, should_fail, top_mod, link, addsuf, comp_flags = copy.copy(getTestOpts().compiler_always_flags) if noforce: - comp_flags = [f for f in comp_flags if f != '-fforce-recomp'] + comp_flags = filter(lambda f: f != '-fforce-recomp', comp_flags) if getTestOpts().outputdir != None: comp_flags.extend(["-outputdir", getTestOpts().outputdir]) cmd = 'cd ' + getTestOpts().testdir + " && " + cmd_prefix + "'" \ + config.compiler + "' " \ - + ' '.join(comp_flags) + ' ' \ + + join(comp_flags,' ') + ' ' \ + to_do + ' ' + srcname + ' ' \ - + ' '.join(config.way_flags(name)[way]) + ' ' \ + + join(config.way_flags(name)[way],' ') + ' ' \ + extra_hc_opts + ' ' \ + opts.extra_hc_opts + ' ' \ + '>' + errname + ' 2>&1' @@ -1170,7 +1166,7 @@ def simple_build( name, way, extra_hc_opts, should_fail, top_mod, link, addsuf, if result != 0 and not should_fail: actual_stderr = qualify(name, 'comp.stderr') - if_verbose(1,'Compile failed (status ' + repr(result) + ') errors were:') + if_verbose(1,'Compile failed (status ' + `result` + ') errors were:') if_verbose_dump(1,actual_stderr) # ToDo: if the sub-shell was killed by ^C, then exit @@ -1254,7 +1250,7 @@ def simple_run( name, way, prog, args ): # check the exit code if exit_code != opts.exit_code: - print('Wrong exit code (expected', opts.exit_code, ', actual', exit_code, ')') + print 'Wrong exit code (expected', opts.exit_code, ', actual', exit_code, ')' dump_stdout(name) dump_stderr(name) return failBecause('bad exit code') @@ -1286,7 +1282,7 @@ def rts_flags(way): if args == []: return '' else: - return '+RTS ' + ' '.join(args) + ' -RTS' + return '+RTS ' + join(args,' ') + ' -RTS' # ----------------------------------------------------------------------------- # Run a program in the interpreter and check its output @@ -1343,9 +1339,9 @@ def interpreter_run( name, way, extra_hc_opts, compile_only, top_mod ): flags.extend(["-outputdir", getTestOpts().outputdir]) cmd = "'" + config.compiler + "' " \ - + ' '.join(flags) + ' ' \ + + join(flags,' ') + ' ' \ + srcname + ' ' \ - + ' '.join(config.way_flags(name)[way]) + ' ' \ + + join(config.way_flags(name)[way],' ') + ' ' \ + extra_hc_opts + ' ' \ + getTestOpts().extra_hc_opts + ' ' \ + '<' + scriptname + ' 1>' + outname + ' 2>' + errname @@ -1370,7 +1366,7 @@ def interpreter_run( name, way, extra_hc_opts, compile_only, top_mod ): # check the exit code if exit_code != getTestOpts().exit_code: - print('Wrong exit code (expected', getTestOpts().exit_code, ', actual', exit_code, ')') + print 'Wrong exit code (expected', getTestOpts().exit_code, ', actual', exit_code, ')' dump_stdout(name) dump_stderr(name) return failBecause('bad exit code') @@ -1432,8 +1428,8 @@ def check_stdout_ok( name ): expected_stdout_file, actual_stdout_file) def dump_stdout( name ): - print('Stdout:') - print(read_no_crs(qualify(name, 'run.stdout'))) + print 'Stdout:' + print read_no_crs(qualify(name, 'run.stdout')) def check_stderr_ok( name ): if getTestOpts().with_namebase == None: @@ -1455,8 +1451,8 @@ def check_stderr_ok( name ): expected_stderr_file, actual_stderr_file) def dump_stderr( name ): - print("Stderr:") - print(read_no_crs(qualify(name, 'run.stderr'))) + print "Stderr:" + print read_no_crs(qualify(name, 'run.stderr')) def read_no_crs(file): str = '' @@ -1491,13 +1487,13 @@ def check_hp_ok(name): if (gsResult == 0): return (True) else: - print("hp2ps output for " + name + "is not valid PostScript") + print "hp2ps output for " + name + "is not valid PostScript" else: return (True) # assume postscript is valid without ghostscript else: - print("hp2ps did not generate PostScript for " + name) + print "hp2ps did not generate PostScript for " + name return (False) else: - print("hp2ps error when processing heap profile for " + name) + print "hp2ps error when processing heap profile for " + name return(False) def check_prof_ok(name): @@ -1505,11 +1501,11 @@ def check_prof_ok(name): prof_file = qualify(name,'prof') if not os.path.exists(prof_file): - print(prof_file + " does not exist") + print prof_file + " does not exist" return(False) if os.path.getsize(qualify(name,'prof')) == 0: - print(prof_file + " is empty") + print prof_file + " is empty" return(False) if getTestOpts().with_namebase == None: @@ -1671,16 +1667,16 @@ def normalise_asm( str ): out = '\n'.join(out) return out -def if_verbose( n, s ): +def if_verbose( n, str ): if config.verbose >= n: - print(s) + print str def if_verbose_dump( n, f ): if config.verbose >= n: try: - print(open(f).read()) + print open(f).read() except: - print('') + print '' def rawSystem(cmd_and_args): # We prefer subprocess.call to os.spawnv as the latter @@ -1908,7 +1904,7 @@ def checkForFilesWrittenProblems(file): if len(files_written_not_removed) > 0: file.write("\n") file.write("\nSome files written but not removed:\n") - tests = list(files_written_not_removed.keys()) + tests = files_written_not_removed.keys() tests.sort() for t in tests: for f in files_written_not_removed[t]: @@ -1920,7 +1916,7 @@ def checkForFilesWrittenProblems(file): if len(bad_file_usages) > 0: file.write("\n") file.write("\nSome bad file usages:\n") - tests = list(bad_file_usages.keys()) + tests = bad_file_usages.keys() tests.sort() for t in tests: for f in bad_file_usages[t]: @@ -1935,7 +1931,7 @@ def genGSCmd(psfile): def gsNotWorking(): global gs_working - print("GhostScript not available for hp2ps tests") + print "GhostScript not available for hp2ps tests" global gs_working gs_working = 0 @@ -1945,7 +1941,7 @@ if config.have_profiling: if resultGood == 0: resultBad = runCmdExitCode(genGSCmd(config.confdir + '/bad.ps')); if resultBad != 0: - print("GhostScript available for hp2ps tests") + print "GhostScript available for hp2ps tests" gs_working = 1; else: gsNotWorking(); @@ -2012,7 +2008,7 @@ def platform_wordsize_qualify( name, suff ): for vers in ['-' + config.compiler_maj_version, '']] dir = glob.glob(basepath + '*') - dir = [normalise_slashes_(d) for d in dir] + dir = map (lambda d: normalise_slashes_(d), dir) for (platformSpecific, f) in paths: if f in dir: @@ -2045,14 +2041,19 @@ def pretest_cleanup(name): # not interested in the return code # ----------------------------------------------------------------------------- -# Return a list of all the files ending in '.T' below directories roots. +# Return a list of all the files ending in '.T' below the directory dir. def findTFiles(roots): - return [os.path.join(path, filename) - for root in roots - for path, dirs, files in os.walk(root) - for filename in files - if filename.endswith('.T')] + return concat(map(findTFiles_,roots)) + +def findTFiles_(path): + if os.path.isdir(path): + paths = map(lambda x, p=path: p + '/' + x, os.listdir(path)) + return findTFiles(paths) + elif path[-2:] == '.T': + return [path] + else: + return [] # ----------------------------------------------------------------------------- # Output a test summary to the specified file object @@ -2063,28 +2064,28 @@ def summary(t, file): printUnexpectedTests(file, [t.unexpected_passes, t.unexpected_failures]) file.write('OVERALL SUMMARY for test run started at ' + time.strftime("%c %Z", t.start_time) + '\n' - + str(datetime.timedelta(seconds= - round(time.time() - time.mktime(t.start_time)))).rjust(8) + + string.rjust(str(datetime.timedelta(seconds= + round(time.time() - time.mktime(t.start_time)))), 8) + ' spent to go through\n' - + repr(t.total_tests).rjust(8) + + string.rjust(`t.total_tests`, 8) + ' total tests, which gave rise to\n' - + repr(t.total_test_cases).rjust(8) + + string.rjust(`t.total_test_cases`, 8) + ' test cases, of which\n' - + repr(t.n_tests_skipped).rjust(8) + + string.rjust(`t.n_tests_skipped`, 8) + ' were skipped\n' + '\n' - + repr(t.n_missing_libs).rjust(8) + + string.rjust(`t.n_missing_libs`, 8) + ' had missing libraries\n' - + repr(t.n_expected_passes).rjust(8) + + string.rjust(`t.n_expected_passes`, 8) + ' expected passes\n' - + repr(t.n_expected_failures).rjust(8) + + string.rjust(`t.n_expected_failures`, 8) + ' expected failures\n' + '\n' - + repr(t.n_framework_failures).rjust(8) + + string.rjust(`t.n_framework_failures`, 8) + ' caused framework failures\n' - + repr(t.n_unexpected_passes).rjust(8) + + string.rjust(`t.n_unexpected_passes`, 8) + ' unexpected passes\n' - + repr(t.n_unexpected_failures).rjust(8) + + string.rjust(`t.n_unexpected_failures`, 8) + ' unexpected failures\n' + '\n') @@ -2107,7 +2108,7 @@ def printUnexpectedTests(file, testInfoss): for testInfos in testInfoss: directories = testInfos.keys() for directory in directories: - tests = list(testInfos[directory].keys()) + tests = testInfos[directory].keys() unexpected += tests if unexpected != []: file.write('Unexpected results from:\n') @@ -2115,30 +2116,30 @@ def printUnexpectedTests(file, testInfoss): file.write('\n') def printPassingTestInfosSummary(file, testInfos): - directories = list(testInfos.keys()) + directories = testInfos.keys() directories.sort() - maxDirLen = max(len(x) for x in directories) + maxDirLen = max(map ((lambda x : len(x)), directories)) for directory in directories: - tests = list(testInfos[directory].keys()) + tests = testInfos[directory].keys() tests.sort() for test in tests: file.write(' ' + directory.ljust(maxDirLen + 2) + test + \ - ' (' + ','.join(testInfos[directory][test]) + ')\n') + ' (' + join(testInfos[directory][test],',') + ')\n') file.write('\n') def printFailingTestInfosSummary(file, testInfos): - directories = list(testInfos.keys()) + directories = testInfos.keys() directories.sort() - maxDirLen = max(len(d) for d in directories) + maxDirLen = max(map ((lambda x : len(x)), directories)) for directory in directories: - tests = list(testInfos[directory].keys()) + tests = testInfos[directory].keys() tests.sort() for test in tests: reasons = testInfos[directory][test].keys() for reason in reasons: file.write(' ' + directory.ljust(maxDirLen + 2) + test + \ ' [' + reason + ']' + \ - ' (' + ','.join(testInfos[directory][test][reason]) + ')\n') + ' (' + join(testInfos[directory][test][reason],',') + ')\n') file.write('\n') def getStdout(cmd): diff --git a/testsuite/driver/testutil.py b/testsuite/driver/testutil.py index ec45e93987..0738683111 100644 --- a/testsuite/driver/testutil.py +++ b/testsuite/driver/testutil.py @@ -1,5 +1,39 @@ # ----------------------------------------------------------------------------- # Utils + +def id(a): + return a + +def eq(x): + return lambda y,z=x: y == z + +def neq(x): + return lambda y,z=x: y != z + +def append(x,y): + return x + y + +def concat(xs): + return reduce(append,xs,[]) + +def chop(s): + if s[len(s)-1:] == '\n': + return s[:len(s)-1] + else: + return s + +def all(p,xs): + for x in xs: + if not p(x): + return False + return True + +def elem(xs): + return lambda x: x in xs + +def notElem(xs): + return lambda x: x not in xs + def version_to_ints(v): return [ int(x) for x in v.split('.') ] diff --git a/testsuite/tests/ffi/should_run/all.T b/testsuite/tests/ffi/should_run/all.T index 6fe087884d..7efc6eb3d8 100644 --- a/testsuite/tests/ffi/should_run/all.T +++ b/testsuite/tests/ffi/should_run/all.T @@ -50,10 +50,10 @@ test('ffi008', [exit_code(1), omit_ways(['ghci'])], compile_and_run, ['']) maybe_skip = normal opts = '' if config.platform.startswith('i386-'): - if config.compiler_type == 'ghc' and \ + if config.compiler_type == 'ghc' and \ version_ge(config.compiler_version, '6.13'): - opts = '-msse2' - else: + opts = '-msse2' + else: maybe_skip = only_ways(['ghci']) test('ffi009', [when(fast(), skip), @@ -69,9 +69,9 @@ test('ffi011', normal, compile_and_run, ['']) # it. if config.os == 'mingw32': - skip_if_not_windows = normal + skip_if_not_windows = normal else: - skip_if_not_windows = skip + skip_if_not_windows = skip test('ffi012', skip_if_not_windows, compile_and_run, ['']) test('ffi013', normal, compile_and_run, ['']) diff --git a/testsuite/tests/numeric/should_run/all.T b/testsuite/tests/numeric/should_run/all.T index 76181a2115..72c8e6a74a 100644 --- a/testsuite/tests/numeric/should_run/all.T +++ b/testsuite/tests/numeric/should_run/all.T @@ -15,11 +15,11 @@ test('arith007', normal, compile_and_run, ['']) ways = normal opts = '' if config.platform.startswith('i386-'): - if config.compiler_type == 'ghc' and \ + if config.compiler_type == 'ghc' and \ version_ge(config.compiler_version, '6.13'): - opts = '-msse2' - else: - ways = expect_fail_for(['optasm','threaded2','hpc','dyn','profasm']) + opts = '-msse2' + else: + ways = expect_fail_for(['optasm','threaded2','hpc','dyn','profasm']) test('arith008', ways, compile_and_run, [opts]) diff --git a/testsuite/tests/perf/compiler/all.T b/testsuite/tests/perf/compiler/all.T index 9868faefac..a7783a4977 100644 --- a/testsuite/tests/perf/compiler/all.T +++ b/testsuite/tests/perf/compiler/all.T @@ -1,6 +1,6 @@ def no_lint(name, opts): opts.compiler_always_flags = \ - [opt for opt in opts.compiler_always_flags if opt != '-dcore-lint' and opt != '-dcmm-lint'] + filter(lambda opt: opt != '-dcore-lint' and opt != '-dcmm-lint', opts.compiler_always_flags) setTestOpts(no_lint) diff --git a/testsuite/tests/programs/seward-space-leak/Main.lhs b/testsuite/tests/programs/seward-space-leak/Main.lhs index 327118d5e3..6c3f9f9d32 100644 --- a/testsuite/tests/programs/seward-space-leak/Main.lhs +++ b/testsuite/tests/programs/seward-space-leak/Main.lhs @@ -64,6 +64,8 @@ Collector: APPEL HeapSize: 4,194,304 (bytes) > module Main where +> import Prelude hiding (traverse) + %============================================================ %============================================================ diff --git a/testsuite/tests/th/all.T b/testsuite/tests/th/all.T index 00f5fc9670..6e86d303e5 100644 --- a/testsuite/tests/th/all.T +++ b/testsuite/tests/th/all.T @@ -4,9 +4,9 @@ test('T4255', unless(compiler_profiled(), skip), compile_fail, ['-v0']) def f(name, opts): - opts.extra_hc_opts = '-XTemplateHaskell -package template-haskell' - if (ghc_with_interpreter == 0): - opts.skip = 1 + opts.extra_hc_opts = '-XTemplateHaskell -package template-haskell' + if (ghc_with_interpreter == 0): + opts.skip = 1 setTestOpts(f) setTestOpts(only_compiler_types(['ghc'])) diff --git a/testsuite/tests/typecheck/should_run/T1735_Help/State.hs b/testsuite/tests/typecheck/should_run/T1735_Help/State.hs index 7b048eb2df..d696af738f 100644 --- a/testsuite/tests/typecheck/should_run/T1735_Help/State.hs +++ b/testsuite/tests/typecheck/should_run/T1735_Help/State.hs @@ -1,6 +1,9 @@ module T1735_Help.State where
+import Control.Monad (ap, liftM)
+
+
newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
instance Monad m => Monad (StateT s m) where
@@ -10,6 +13,13 @@ instance Monad m => Monad (StateT s m) where runStateT (k a) s'
fail str = StateT $ \_ -> fail str
+instance Monad m => Functor (StateT s m) where
+ fmap = liftM
+
+instance Monad m => Applicative (StateT s m) where
+ pure = return
+ (<*>) = ap
+
get :: Monad m => StateT s m s
get = StateT $ \s -> return (s, s)
diff --git a/testsuite/tests/typecheck/should_run/T5751.hs b/testsuite/tests/typecheck/should_run/T5751.hs index f620d8fb63..cf1142195b 100644 --- a/testsuite/tests/typecheck/should_run/T5751.hs +++ b/testsuite/tests/typecheck/should_run/T5751.hs @@ -12,7 +12,7 @@ class XMLGenerator m where genElement :: (Maybe String, String) -> m () newtype IdentityT m a = IdentityT { runIdentityT :: m a } - deriving (Monad, MonadIO) + deriving (Functor, Applicative, Monad, MonadIO) instance (MonadIO m) => (XMLGenerator (IdentityT m)) where genElement _ = liftIO $ putStrLn "in genElement" diff --git a/testsuite/tests/typecheck/should_run/all.T b/testsuite/tests/typecheck/should_run/all.T index 5da7c8b169..760d5e1452 100755 --- a/testsuite/tests/typecheck/should_run/all.T +++ b/testsuite/tests/typecheck/should_run/all.T @@ -19,8 +19,8 @@ test('TcCoercible', when(compiler_lt('ghc', '7.7'), skip), compile_and_run, [''] # Skip everything else if fast is on def f(name, opts): - if config.fast: - opts.skip = 1 + if config.fast: + opts.skip = 1 setTestOpts(f) test('tcrun006', normal, compile_and_run, ['']) diff --git a/testsuite/tests/typecheck/should_run/tcrun036.hs b/testsuite/tests/typecheck/should_run/tcrun036.hs index cef36a613d..64fffb7fde 100644 --- a/testsuite/tests/typecheck/should_run/tcrun036.hs +++ b/testsuite/tests/typecheck/should_run/tcrun036.hs @@ -21,6 +21,8 @@ module Main where +import Prelude hiding (traverse) + class Catalog c where traverse :: c -> Viewer -> IO () diff --git a/testsuite/timeout/calibrate b/testsuite/timeout/calibrate index f30c628e7a..b0d75dac24 100644 --- a/testsuite/timeout/calibrate +++ b/testsuite/timeout/calibrate @@ -10,7 +10,7 @@ except: # We don't have resource, so this is a non-UNIX machine. # It's probably a reasonable modern x86/x86_64 machines, so we'd # probably calibrate to 300 anyway; thus just print 300. - print(300) + print 300 exit(0) compiler = argv[1] diff --git a/testsuite/timeout/timeout.py b/testsuite/timeout/timeout.py index df50806b9b..6a57ac2f82 100644 --- a/testsuite/timeout/timeout.py +++ b/testsuite/timeout/timeout.py @@ -21,7 +21,7 @@ try: os.killpg(pid, signal.SIGKILL) else: return - except OSError as e: + except OSError, e: if e.errno == errno.ECHILD: return else: diff --git a/utils/fingerprint/fingerprint.py b/utils/fingerprint/fingerprint.py index 628e0c85bb..5738cda8cc 100755 --- a/utils/fingerprint/fingerprint.py +++ b/utils/fingerprint/fingerprint.py @@ -1,8 +1,6 @@ #! /usr/bin/env python # Script to create and restore a git fingerprint of the ghc repositories. -from __future__ import print_function - from datetime import datetime from optparse import OptionParser import os @@ -25,7 +23,7 @@ def create_action(opts): if len(fp) == 0: error("Got empty fingerprint from source: "+str(opts.source)) if opts.output_file: - print("Writing fingerprint to: ", opts.output_file) + print "Writing fingerprint to: ", opts.output_file fp.write(opts.output) def restore_action(opts): @@ -91,7 +89,7 @@ def restore(fp, branch_name=None): for (subdir, commit) in fp: if subdir != ".": cmd = checkout + [commit] - print("==", subdir, " ".join(cmd)) + print "==", subdir, " ".join(cmd) if os.path.exists(subdir): rc = subprocess.call(cmd, cwd=subdir) if rc != 0: @@ -186,7 +184,7 @@ def validate(opts, args, parser): def error(msg="fatal error", parser=None, exit=1): """Function that prints error message and exits""" - print("ERROR:", msg) + print "ERROR:", msg if parser: parser.print_help() sys.exit(exit) |