diff --git a/pkgs/os-specific/linux/kernel/manual-config.nix b/pkgs/os-specific/linux/kernel/manual-config.nix index 5d2a42646bf6..7cec47b86be9 100644 --- a/pkgs/os-specific/linux/kernel/manual-config.nix +++ b/pkgs/os-specific/linux/kernel/manual-config.nix @@ -1,4 +1,4 @@ -{ stdenv, runCommand, nettools, perl, kmod, writeTextFile }: +{ stdenv, runCommand, nettools, perl, kmod, writeTextFile, coffeescript }: with stdenv.lib; @@ -7,25 +7,65 @@ let # Function to parse the config file to get the features supported readFeatures = config: let - # !!! Original causes recursion too deep, need to import from derivation - # linesWithComments = splitString "\n" (builtins.readFile config); - lines = import "${runCommand "lines.nix" {} '' - echo "[" >> $out - while read line; do - if [ -n "$line" ] && [ "#" != ''${line:0:1} ]; then - echo "'''" >> $out - echo $(echo $line | sed "s/'''/''''/g")"'''" >> $out - fi - done < ${config} - echo "]" >> $out - ''}"; + configParser = writeTextFile { name = "config-parser"; executable=true; text = '' + #!${coffeescript}/bin/coffee + fs = require "fs" + events = require "events" - nvpairs = map (s: let split = splitString "=" s; fst = head split; in { - name = substring (stringLength "CONFIG_") (stringLength fst) fst; - value = head (tail split); - }) lines; + lineEmitter = new events.EventEmitter() + buffer = new Buffer 0 + input = fs.createReadStream process.argv[2] + input.on 'data', (data) -> + nextBuffer = new Buffer buffer.length + data.length + buffer.copy(nextBuffer) + data.copy(nextBuffer, buffer.length) + start = 0 + offset = buffer.length + buffer = nextBuffer - configAttrs = listToAttrs nvpairs; + for i in [1..data.length] + if data[i] == '\n'.charCodeAt 0 + end = i+offset+1 + line = buffer.slice start, end - 1 + start = end + lineEmitter.emit "line", line.toString() + + buffer = buffer.slice start + input.once 'end', -> + input.destroy() + if safeToWrite + output.end "}" + output.destroySoon() + else + output.once 'drain', -> + output.end "}" + output.destroySoon() + + output = fs.createWriteStream process.env["out"] + output.setMaxListeners 0 + safeToWrite = output.write "{\n" + unless safeToWrite + output.once 'drain', -> + safeToWrite = true + + escapeNixString = (str) -> + str.replace("'''", "''''").replace("''${", "'''''${") + lineEmitter.on 'line', (line) -> + unless line.length is 0 or line.charAt(0) is '#' + split = line.split '=' + name = split[0].substring "CONFIG_".length + value = escapeNixString split.slice(1).join "" + lineToWrite = "\"#{name}\" = '''#{value}''';\n" + if safeToWrite + safeToWrite = output.write lineToWrite + else + input.pause() + output.once 'drain', -> + safeToWrite = output.write lineToWrite + input.resume() + '';}; + + configAttrs = import "${runCommand "attrList.nix" {} "${configParser} ${config}"}"; getValue = option: if hasAttr option configAttrs then getAttr option configAttrs else null; diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 88e1626e5801..69f9a352d8a6 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -5858,7 +5858,8 @@ let # A function to build a manually-configured kernel linuxManualConfig = import ../os-specific/linux/kernel/manual-config.nix { - inherit stdenv runCommand nettools perl kmod writeTextFile; + inherit (pkgs) stdenv runCommand nettools perl kmod writeTextFile; + coffeescript = pkgs.nodePackages."coffee-script"; }; keyutils = callPackage ../os-specific/linux/keyutils { };