<commit_before>ArgParser = function(options, parserOpts) {
  this.options = options || [];
  parserOpts = parserOpts || {};
  this.print = parserOpts.printFunc || this.print;
  this.script = parserOpts.script;
  this.printHelp = parserOpts.printHelp;
  if(this.printHelp == undefined)
    this.printHelp = true;
}

ArgParser.prototype = {
  print : function(str) {
    require("sys").puts(str);
    process.exit(0);
  },
  
  getOption : function(arg) {
    var match = {};
    this.options.forEach(function(option) {
      var longOpt = new Arg(option.long);
      if(longOpt.isLong() && longOpt.getKey() == arg)
        match = option;

      var opt = new Arg(option.string);
      if(opt.isShort() && opt.getChars() == arg
         || opt.isLong() && opt.getKey() == arg)
        match = option;

      if(option.position == arg)
        match = option;
    });
    return match;
  },
  
  getOptName : function(arg) {
    if(typeof arg == "object") {
      // parse the name out of e.g. '--config=example.txt'
      var option = arg;
      return option.name || new Arg(option.string).getKey()
       || new Arg(option.long).getKey();
    }
    return this.getOption(arg).name || arg;
  },
  
  getDefault : function(arg) {
    return this.getOption(arg).default || true;
  },
  
  expectsValue : function(arg) {
    var option = this.getOption(arg);
    return (new Arg(option.string)).expectsValue() || 
      (new Arg(option.long)).expectsValue() || option.default;
  },
  
  parse : function(args) {
    args = args || process.argv.slice(2);

    if(this.printHelp && (args.indexOf("--help") != -1
         || args.indexOf("-h") != -1))
      this.print(this.helpString());
  
    var ret = {};
    this.options.forEach(function(option) {
      ret[this.getOptName(option)] = option.default;
    }, this);
    
    args = args.concat([""]).map(function(arg) {
      return new Arg(arg);
    });
    var positionals = [];
    var that = this;
    
    args.reduce(function(arg, val) {
      /* word */
      if(arg.isValue()) {
        positionals.push(arg.getValue());
      }
      /* -c */
      else if(arg.isShort()) {
        /* -cfv */
        (arg.getChars()).forEach(function(ch) {
          ret[this.getOptName(ch)] = this.getDefault(ch);
        }, that);
        /* -c 3 */
        if(val.isValue()) {
          var value = val.getValue();
          var last = arg.lastChar();
          if(that.expectsValue(last)) {
            ret[that.getOptName(last)] = value;
            return new Arg(""); // skip next turn - swallow arg
          }
        }
      }
      /* --config=tests.json */
      else if(arg.isLong()) {
        var key = arg.getKey()
        var value = arg.getValue()
        /* --debug */
        if(value == undefined)
          value = that.getDefault(key)
        ret[that.getOptName(key)] = value;
      }
      return val;
    });

    positionals.forEach(function(pos, index) {
      ret[this.getOptName(index)] = pos;
    }, this);

    return ret;
  },
  
  helpString : function() {
    var str = "usage: " + (this.script || "<script>");

    var positionals = this.options.filter(function(opt) {
      return opt.position != undefined;
    }).sort(function(opt1, opt2) {
      return opt1.position > opt2.position;
    });
    // assume there are no gaps in the specified pos. args
    positionals.forEach(function(pos) {
      str += " " + (pos.name || "arg" + pos.position); 
    });
    str += " [options]\n\noptions:\n"
    
    this.options.forEach(function(option) {
      if(option.position != undefined)
        return;
      var sh = "";
      if((new Arg(option.string)).isShort())
        sh = option.string;
      var lg = "";
      if((new Arg(option.string)).isLong())
        lg = option.string;
      else if((new Arg(option.long)).isLong())
        lg = option.long;
      if(sh && lg)
        sh += ", ";      
      var help = option.help || "";
      
      str += sh + lg + "\t" + help + "\n";
    });
    return str;
  }
}

Arg = function(str) {
  this.str = str ;
}

Arg.prototype = {
  shortRegex : /^\-(\w+?)(?:\s+(\w*))?$/,
  
  longRegex : /^\-\-(.+?)(?:=(.+))?$/,
  
  isShort : function() {<commit_msg>allow other chars in short arg string<commit_after>ArgParser = function(options, parserOpts) {
  this.options = options || [];
  parserOpts = parserOpts || {};
  this.print = parserOpts.printFunc || this.print;
  this.script = parserOpts.script;
  this.printHelp = parserOpts.printHelp;
  if(this.printHelp == undefined)
    this.printHelp = true;
}

ArgParser.prototype = {
  print : function(str) {
    require("sys").puts(str);
    process.exit(0);
  },
  
  getOption : function(arg) {
    var match = {};
    this.options.forEach(function(option) {
      var longOpt = new Arg(option.long);
      if(longOpt.isLong() && longOpt.getKey() == arg)
        match = option;

      var opt = new Arg(option.string);
      if(opt.isShort() && opt.getChars() == arg
         || opt.isLong() && opt.getKey() == arg)
        match = option;

      if(option.position == arg)
        match = option;
    });
    return match;
  },
  
  getOptName : function(arg) {
    if(typeof arg == "object") {
      // parse the name out of e.g. '--config=example.txt'
      var option = arg;
      return option.name || new Arg(option.string).getKey()
       || new Arg(option.long).getKey();
    }
    return this.getOption(arg).name || arg;
  },
  
  getDefault : function(arg) {
    return this.getOption(arg).default || true;
  },
  
  expectsValue : function(arg) {
    var option = this.getOption(arg);
    return (new Arg(option.string)).expectsValue() || 
      (new Arg(option.long)).expectsValue() || option.default;
  },
  
  parse : function(args) {
    args = args || process.argv.slice(2);

    if(this.printHelp && (args.indexOf("--help") != -1
         || args.indexOf("-h") != -1))
      this.print(this.helpString());
  
    var ret = {};
    this.options.forEach(function(option) {
      ret[this.getOptName(option)] = option.default;
    }, this);
    
    args = args.concat([""]).map(function(arg) {
      return new Arg(arg);
    });
    var positionals = [];
    var that = this;
    
    args.reduce(function(arg, val) {
      /* word */
      if(arg.isValue()) {
        positionals.push(arg.getValue());
      }
      /* -c */
      else if(arg.isShort()) {
        /* -cfv */
        (arg.getChars()).forEach(function(ch) {
          ret[this.getOptName(ch)] = this.getDefault(ch);
        }, that);
        /* -c 3 */
        if(val.isValue()) {
          var value = val.getValue();
          var last = arg.lastChar();
          if(that.expectsValue(last)) {
            ret[that.getOptName(last)] = value;
            return new Arg(""); // skip next turn - swallow arg
          }
        }
      }
      /* --config=tests.json */
      else if(arg.isLong()) {
        var key = arg.getKey()
        var value = arg.getValue()
        /* --debug */
        if(value == undefined)
          value = that.getDefault(key)
        ret[that.getOptName(key)] = value;
      }
      return val;
    });

    positionals.forEach(function(pos, index) {
      ret[this.getOptName(index)] = pos;
    }, this);

    return ret;
  },
  
  helpString : function() {
    var str = "usage: " + (this.script || "<script>");

    var positionals = this.options.filter(function(opt) {
      return opt.position != undefined;
    }).sort(function(opt1, opt2) {
      return opt1.position > opt2.position;
    });
    // assume there are no gaps in the specified pos. args
    positionals.forEach(function(pos) {
      str += " " + (pos.name || "arg" + pos.position); 
    });
    str += " [options]\n\noptions:\n"
    
    this.options.forEach(function(option) {
      if(option.position != undefined)
        return;
      var sh = "";
      if((new Arg(option.string)).isShort())
        sh = option.string;
      var lg = "";
      if((new Arg(option.string)).isLong())
        lg = option.string;
      else if((new Arg(option.long)).isLong())
        lg = option.long;
      if(sh && lg)
        sh += ", ";      
      var help = option.help || "";
      
      str += sh + lg + "\t" + help + "\n";
    });
    return str;
  }
}

Arg = function(str) {
  this.str = str ;
}

Arg.prototype = {
  shortRegex : /^\-(\w+?)(?:\s+(.*))?$/,
  
  longRegex : /^\-\-(.+?)(?:=(.+))?$/,
  
  isShort : function() {
{'fraction_non_alphanumeric': 0.1791293977340489, 'fraction_numerical': 0.002146690518783542, 'mean_word_length': 2.120952735392631, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5164897', 'n_tokens_mistral': 2744, 'n_tokens_neox': 2738, 'n_words': 526}