From 1b5ee3681e56187bdfb4bbe83be8e4b28bb05874 Mon Sep 17 00:00:00 2001 From: Daniel Wirtz Date: Thu, 10 Oct 2013 03:41:45 +0200 Subject: [PATCH] Inline defines, fixes #5 --- Preprocessor.js | 63 +++++++++++++---- Preprocessor.min.js | 21 +++--- Preprocessor.min.map | 6 +- README.md | 8 +++ docs/Preprocessor.html | 148 ++++++++++++++++++++++++++++++++++++++-- externs/Preprocessor.js | 10 +-- package.json | 2 +- tests/define.js | 3 + tests/suite.js | 7 ++ 9 files changed, 230 insertions(+), 38 deletions(-) create mode 100644 tests/define.js diff --git a/Preprocessor.js b/Preprocessor.js index 537bf39..315ea74 100644 --- a/Preprocessor.js +++ b/Preprocessor.js @@ -65,13 +65,19 @@ * @expose */ this.errorSourceAhead = 50; + + /** + * Runtime defines. + * @type {Array.} + */ + this.defines = []; }; /** * Definition expression * @type {RegExp} */ - Preprocessor.EXPR = /([ ]*)\/\/[ ]+#(include|ifn?def|if|endif|else|elif|put)/g; + Preprocessor.EXPR = /([ ]*)\/\/[ ]+#(include|ifn?def|if|endif|else|elif|put|define)/g; /** * #include "path/to/file". Requires node.js' "fs" module. @@ -97,6 +103,12 @@ */ Preprocessor.PUT = /put[ ]+([^\n]+)[ ]*/g; + /** + * #define EXPRESSION + * @type {RegExp} + */ + Preprocessor.DEFINE = /define[ ]+([^\n]+)\r?(?:\n|$)/g; + /** * Strips slashes from an escaped string. * @param {string} str Escaped string @@ -152,27 +164,38 @@ /** * Evaluates an expression. - * @param {object.} defines Defines - * @param {string} expr Expression to evaluate + * @param {object.} runtimeDefines Runtime defines + * @param {Array.|string} inlineDefines Inline defines (optional for backward compatibility) + * @param {string=} expr Expression to evaluate * @return {*} Expression result * @throws {Error} If the expression cannot be evaluated * @expose */ - Preprocessor.evaluate = function(defines, expr) { + Preprocessor.evaluate = function(runtimeDefines, inlineDefines, expr) { + if (typeof inlineDefines === 'string') { + expr = inlineDefines; + inlineDefines = []; + } var addSlashes = Preprocessor.addSlashes; - return (function(defines, expr) { - var Preprocessor = null; - for (var key in defines) { - if (defines.hasOwnProperty(key)) { - eval("var "+key+" = \""+addSlashes(""+defines[key])+"\";"); + return (function(runtimeDefines, inlineDefines, expr) { + for (var key in runtimeDefines) { + if (runtimeDefines.hasOwnProperty(key)) { + eval("var "+key+" = \""+addSlashes(""+runtimeDefines[key])+"\";"); + } + } + for (var i=0; i} defines Defines * @param {function(string)=} verbose Print verbose processing information to the specified function as the first parameter. Defaults to not print debug information. * @return {string} Processed source @@ -221,7 +244,7 @@ } include = match2[1]; verbose(" expr: "+match2[1]); - include = Preprocessor.evaluate(defines, match2[1]); + include = Preprocessor.evaluate(defines, this.defines, match2[1]); verbose(" value: "+Preprocessor.nlToStr(include)); this.source = this.source.substring(0, match.index)+indent+include+this.source.substring(Preprocessor.PUT.lastIndex); Preprocessor.EXPR.lastIndex = match.index + include.length; @@ -240,7 +263,7 @@ } else if (match2[1] == "ifndef") { include = !defines[match2[2]]; } else { - include = Preprocessor.evaluate(defines, match2[2]); + include = Preprocessor.evaluate(defines, this.defines, match2[2]); } verbose(" value: "+include); stack.push(p={ @@ -280,7 +303,7 @@ if (match2[1] == 'else') { include = !before["include"]; } else { - include = Preprocessor.evaluate(defines, match2[2]); + include = Preprocessor.evaluate(defines, this.defines, match2[2]); } stack.push(p={ "include": !before["include"], @@ -290,6 +313,18 @@ verbose(" push: "+JSON.stringify(p)); } break; + case 'define': + // https://github.com/dcodeIO/Preprocessor.js/issues/5 + Preprocessor.DEFINE.lastIndex = match.index; + if ((match2 = Preprocessor.DEFINE.exec(this.source)) === null) { + throw(new Error("Illegal #"+match[2]+": "+this.source.substring(match.index, match.index+this.errorSourceAhead)+"...")); + } + var define = match2[1]; + verbose(" def: "+match2[1]); + this.defines.push(define); + this.source = this.source.substring(0, match.index)+indent+this.source.substring(Preprocessor.DEFINE.lastIndex); + Preprocessor.EXPR.lastIndex = match.index; + verbose(" continue at "+Preprocessor.EXPR.lastIndex); } } if (stack.length > 0) { diff --git a/Preprocessor.min.js b/Preprocessor.min.js index 5493d43..b97678b 100644 --- a/Preprocessor.min.js +++ b/Preprocessor.min.js @@ -3,13 +3,14 @@ Released under the Apache License, Version 2.0 see: https://github.com/dcodeIO/Preprocessor.js for details */ -var k=null; -(function(l){function a(a,c){this.source=""+a;this.baseDir="string"==typeof c?c:".";this.f="object"==typeof c?c:{};this.isNode=("undefined"==typeof window||!window.window)&&"function"==typeof require;this.errorSourceAhead=50}a.a=/([ ]*)\/\/[ ]+#(include|ifn?def|if|endif|else|elif|put)/g;a.d=/include[ ]+"([^"\\]*(\\.[^"\\]*)*)"[ ]*\r?(?:\n|$)/g;a.c=/(ifdef|ifndef|if)[ ]*([^\r\n]+)\r?\n/g;a.b=/(endif|else|elif)([ ]+[^\r\n]+)?\r?(?:\n|$)/g;a.e=/put[ ]+([^\n]+)[ ]*/g;a.stripSlashes=function(a){return(a+"").replace(/\\(.?)/g, -function(a,b){switch(b){case "\\":return"\\";case "0":return"\x00";case "":return"";default:return b}})};a.addSlashes=function(a){return(a+"").replace(/([\\"'])/g,"\\$1").replace(/\0/g,"\\0")};a.indent=function(a,c){for(var b=a.split("\n"),e=0;eMembers
+
+

<static> DEFINE :RegExp

+ + +
+
+ +
+ #define EXPRESSION +
+ + + +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + +

<static> ENDIF :RegExp

@@ -464,6 +509,51 @@

baseDir + + + + + + + +
+

defines :Array.<string>

+ + +
+
+ +
+ Runtime defines. +
+ + + +
+ + + + + + + + + + + + + + + + + + + + @@ -790,7 +880,7 @@
Returns:
-

<static> evaluate(defines, expr) → {*}

+

<static> evaluate(runtimeDefines, inlineDefines, expr) → {*}

@@ -820,6 +910,8 @@
Parameters:
Type + Argument + @@ -832,23 +924,61 @@
Parameters:
- defines + runtimeDefines -object.<strin,string> +object.<string,string> + + + + + - Defines + + Runtime defines + + + + + + + inlineDefines + + + + + +Array.<string> +| + +string + + + + + + + + + + + + + + + + Inline defines (optional for backward compatibility) @@ -868,6 +998,14 @@
Parameters:
+ + + <optional>
+ + + + + @@ -1374,7 +1512,7 @@

process - Runs the Preprocesses. + Preprocesses. diff --git a/externs/Preprocessor.js b/externs/Preprocessor.js index e8bbb2e..0d047d7 100644 --- a/externs/Preprocessor.js +++ b/externs/Preprocessor.js @@ -63,16 +63,16 @@ Preprocessor.indent = function(str, indent) {}; Preprocessor.nlToStr = function(str) {}; /** - * @param {object.} defines - * @param {string} expr + * @param {Object.} runtimeDefines + * @param {Array.|string} inlineDefines + * @param {string=} expr * @return {*} * @throws {Error} - * @nosideeffects */ -Preprocessor.evaluate = function(defines, expr) {}; +Preprocessor.evaluate = function(runtimeDefines, inlineDefines, expr) {}; /** - * @param {object.} directives + * @param {Object.} directives * @return {string} */ Preprocessor.prototype.process = function(directives) {}; diff --git a/package.json b/package.json index df935eb..55310a7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "preprocessor", - "version": "1.0.4", + "version": "1.1.0", "author": "Daniel Wirtz ", "description": "Preprocessor.js: A JavaScript source file preprocessor, e.g. to build different versions of a library.", "main": "Preprocessor.js", diff --git a/tests/define.js b/tests/define.js new file mode 100644 index 0000000..c45594d --- /dev/null +++ b/tests/define.js @@ -0,0 +1,3 @@ +// #define PI=Math.PI +// #define function RADTODEG(x){return x*180/PI} +var angle = // #put RADTODEG(3)+";" diff --git a/tests/suite.js b/tests/suite.js index 46e7296..33174dd 100644 --- a/tests/suite.js +++ b/tests/suite.js @@ -57,6 +57,13 @@ var suite = { var src = pp.process({"VERSION": "1.0"}, console.log).replace(/\r/, ""); test.equal(src, ' console.log("2==2")\n console.log("VERSION=="+"1.0");\n'); test.done(); + }, + + "define": function(test) { + var pp = new Preprocessor(fs.readFileSync(__dirname+"/define.js"), __dirname); + var src = pp.process({}, console.log).replace(/\r/, ""); + test.equal(src, 'var angle = 171.88733853924697;\n'); + test.done(); } };