employ a better parser for command-line arguments
authorMihai Bazon <mihai@bazon.net>
Wed, 17 Oct 2012 12:56:45 +0000 (15:56 +0300)
committerMihai Bazon <mihai@bazon.net>
Wed, 17 Oct 2012 12:56:45 +0000 (15:56 +0300)
to support passing commas in strings in for example:

    uglifyjs2 -cd TEST="'a,b'" <<EOF
    console.log(TEST);
    EOF

    → console.log("a,b")

close #14

bin/uglifyjs2
lib/compress.js

index 62f5910..acca760 100755 (executable)
@@ -97,9 +97,9 @@ if (ARGS.acorn) {
     acorn = require("acorn");
 }
 
-var COMPRESS = getOptions("c");
-var MANGLE = getOptions("m");
-var BEAUTIFY = getOptions("b");
+var COMPRESS = getOptions("c", true);
+var MANGLE = getOptions("m", true);
+var BEAUTIFY = getOptions("b", true);
 
 if (COMPRESS && ARGS.d) {
     COMPRESS.global_defs = getOptions("d");
@@ -299,16 +299,36 @@ function normalize(o) {
     }
 }
 
-function getOptions(x) {
+function getOptions(x, constants) {
     x = ARGS[x];
     if (!x) return null;
     var ret = {};
     if (x !== true) {
-        x.replace(/^\s+|\s+$/g).split(/\s*,+\s*/).forEach(function(opt){
-            var a = opt.split(/\s*[=:]\s*/);
-            ret[a[0]] = a.length > 1 ? new Function("return(" + a[1] + ")")() : true;
-        });
-        normalize(ret);
+        var ast;
+        try {
+            ast = UglifyJS.parse(x);
+        } catch(ex) {
+            if (ex instanceof UglifyJS.JS_Parse_Error) {
+                sys.error("Error parsing arguments in: " + x);
+                process.exit(1);
+            }
+        }
+        ast.walk(new UglifyJS.TreeWalker(function(node){
+            if (node instanceof UglifyJS.AST_Toplevel) return; // descend
+            if (node instanceof UglifyJS.AST_SimpleStatement) return; // descend
+            if (node instanceof UglifyJS.AST_Seq) return; // descend
+            if (node instanceof UglifyJS.AST_Assign) {
+                var name = node.left.print_to_string({ beautify: false }).replace(/-/g, "_");
+                var value = node.right;
+                if (constants)
+                    value = new Function("return (" + value.print_to_string() + ")")();
+                ret[name] = value;
+                return true;    // no descend
+            }
+            sys.error(node.TYPE)
+            sys.error("Error parsing arguments in: " + x);
+            process.exit(1);
+        }));
     }
     return ret;
 }
index f216ed2..4a51a49 100644 (file)
@@ -134,6 +134,17 @@ merge(Compressor.prototype, {
     };
 
     function make_node_from_constant(compressor, val, orig) {
+        // XXX: WIP.
+        // if (val instanceof AST_Node) return val.transform(new TreeTransformer(null, function(node){
+        //     if (node instanceof AST_SymbolRef) {
+        //         var scope = compressor.find_parent(AST_Scope);
+        //         var def = scope.find_variable(node);
+        //         node.thedef = def;
+        //         return node;
+        //     }
+        // })).transform(compressor);
+
+        if (val instanceof AST_Node) return val.transform(compressor);
         switch (typeof val) {
           case "string":
             return make_node(AST_String, orig, {