# -------------- post unzip steps --------------------------------------------- import strutils, os, osproc, streams, browsers const arch = $(sizeof(int)*8) mingw = "mingw$1.7z" % arch url = r"https://nim-lang.org/download/" & mingw var interactive = true type DownloadResult = enum Failure, Manual, Success proc expand(s: string): string = try: result = expandFilename(s) except OSError, IOError: result = s proc unzip(): bool = if not fileExists("dist" / mingw): echo "Could not find ", "dist" / mingw return false try: let p = osproc.startProcess(r"bin\7zG.exe", getCurrentDir() / r"dist", ["x", mingw]) if p.waitForExit != 0: echo "Unpacking failed: " & mingw else: result = true except: result = false proc downloadMingw(): DownloadResult = let curl = findExe"curl" var cmd: string if curl.len > 0: cmd = quoteShell(curl) & " --output " & "dist" / mingw & " " & url elif fileExists"bin/nimgrab.exe": cmd = r"bin\nimgrab.exe " & url & " dist" / mingw if cmd.len > 0: if execShellCmd(cmd) != 0: echo "download failed! ", cmd if interactive: openDefaultBrowser(url) result = Manual else: result = Failure else: if unzip(): result = Success else: if interactive: openDefaultBrowser(url) result = Manual else: result = Failure when defined(windows): import registry proc askBool(m: string): bool = stdout.write m if not interactive: stdout.writeLine "y (non-interactive mode)" return true while true: try: let answer = stdin.readLine().normalize case answer of "y", "yes": return true of "n", "no": return false else: echo "Please type 'y' or 'n'" except EOFError: quit(1) proc askNumber(m: string; a, b: int): int = stdout.write m stdout.write " [" & $a & ".." & $b & "] " if not interactive: stdout.writeLine $a & " (non-interactive mode)" return a while true: let answer = stdin.readLine() try: result = parseInt answer if result < a or result > b: raise newException(ValueError, "number out of range") break except ValueError: echo "Please type in a number between ", a, " and ", b proc patchConfig(mingw: string) = const cfgFile = "config/nim.cfg" lookFor = """#gcc.path = r"$nim\dist\mingw\bin"""" replacePattern = """gcc.path = r"$1"""" try: let cfg = readFile(cfgFile) let newCfg = cfg.replace(lookFor, replacePattern % mingw) if newCfg == cfg: echo "Could not patch 'config/nim.cfg' [Error]" echo "Reason: patch substring not found:" echo lookFor else: writeFile(cfgFile, newCfg) except IOError: echo "Could not access 'config/nim.cfg' [Error]" proc tryGetUnicodeValue(path, key: string; handle: HKEY): string = try: result = getUnicodeValue(path, key, handle) except: result = "" proc addToPathEnv*(e: string) = var p = tryGetUnicodeValue(r"Environment", "Path", HKEY_CURRENT_USER) i
## Nim Compiler

- This directory contains the Nim compiler written in Nim.
- Note that this code has been translated from a bootstrapping version written in Pascal.
- So the code is **not** a poster child of good Nim code.

See [Internals of the Nim Compiler](https://nim-lang.github.io/Nim/intern.html) for more information.
compatible MingW candidates found " & "in the standard locations [Error]" else: echo "Patching Nim's config to use:" echo alternative patchConfig(alternative) else: if askBool("Found a MingW directory that is not in your PATH.\n" & alternative & "\nShould it be added to your PATH permanently? (y/n) "): addToPathEnv(alternative) elif askBool("Do you want to patch Nim's config to use this? (y/n) "): patchConfig(alternative) elif mingWchoices.len == 1: if askBool("MingW installation found at " & mingWchoices[0] & "\n" & "Do you want to patch Nim's config to use this?\n" & "(Not required since it's in your PATH!) (y/n) "): patchConfig(mingWchoices[0]) else: echo "Multiple MingW installations found: " for i in 0..high(mingWchoices): echo "[", i, "] ", mingWchoices[i] if askBool("Do you want to patch Nim's config to use one of these? (y/n) "): let idx = askNumber("Which one do you want to use for Nim? ", 1, len(mingWchoices)) patchConfig(mingWchoices[idx-1]) createStartMenuEntry() else: echo("Add ", getCurrentDir(), "/bin to your PATH...") when isMainModule: when defined(testdownload): discard downloadMingw() else: if "-y" in commandLineParams(): interactive = false main()