<commit_before>'use strict';

var stackTrace = require('stack-trace');
var path = require('path');
var fs = require('fs');
var color = require('ansicolors');
var lu = require('./prelude');



function getCallerCodeLine(frameNum, numLinesAround){
  var frame = stackTrace.get(getCallerCodeLine)[frameNum];
  var source = getSource(frame, numLinesAround);
  var fileName = frame.getFileName();
  source.dirname = path.dirname(fileName);
  source.basename = path.basename(fileName);
  source.render = render.bind(null, source.lines);
  return source;
}

function render(lines_){
  var lines = lines_.slice();
  // var lines_str = lines.map(function(x){ return lu.space(4) + x; }).join('\n');
  var lines_str = lines.join('\n');
  return lines_str;
}


// Frame helpers

function getSource(frame, numLinesAround){
  var code;
  var source = {
    line: '',
    lines: ''
  };
  try {
    code = fs.readFileSync(frame.getFileName()).toString().split('\n');
  } catch (err) {
    console.warn('getCallerCodeLine unable to read file %j.', frame.getFileName());
    console.trace(err);
    return source;
  }
  var lineNumber = frame.getLineNumber();
  var snipStart = lineNumber - numLinesAround;
  var snipEnd = lineNumber + numLinesAround;
  var lines = code.slice(snipStart, snipEnd);
  lines.forEach(function(line, i){
    var thisLineNumber = snipStart + i + 1;
    var withLineNumber = thisLineNumber + '   ' + line;
    if (thisLineNumber !== lineNumber){
      withLineNumber = color.black(withLineNumber);
    }
    lines[i] = withLineNumber;
  });
  source.lines = lines;
  source.line = lines.slice(numLinesAround-1, numLinesAround)[0];
  return source;
}
<commit_msg>guard against case where source code is smaller than lines asked for<commit_after>'use strict';

var stackTrace = require('stack-trace');
var path = require('path');
var fs = require('fs');
var color = require('ansicolors');
var lu = require('./prelude');



function getCallerCodeLine(frameNum, numLinesAround){
  var frame = stackTrace.get(getCallerCodeLine)[frameNum];
  var source = getSource(frame, numLinesAround);
  var fileName = frame.getFileName();
  source.dirname = path.dirname(fileName);
  source.basename = path.basename(fileName);
  source.render = render.bind(null, source.lines);
  return source;
}

function render(lines_){
  var lines = lines_.slice();
  // var lines_str = lines.map(function(x){ return lu.space(4) + x; }).join('\n');
  var lines_str = lines.join('\n');
  return lines_str;
}


// Frame helpers

function getSource(frame, numLinesAround){
  var code;
  var source = {
    line: '',
    lines: ''
  };
  try {
    code = fs.readFileSync(frame.getFileName()).toString().split('\n');
  } catch (err) {
    console.warn('getCallerCodeLine unable to read file %j.', frame.getFileName());
    console.trace(err);
    return source;
  }
  var lineNumber = frame.getLineNumber();
  var snipStart = lineNumber - numLinesAround;
  var snipEnd = lineNumber + numLinesAround;
  var lines = code.slice(snipStart, snipEnd);
  lines.forEach(function(line, i){
    var thisLineNumber = snipStart + i + 1;
    var withLineNumber = thisLineNumber + '   ' + line;
    if (thisLineNumber !== lineNumber){
      withLineNumber = color.black(withLineNumber);
    }
    lines[i] = withLineNumber;
  });
  source.lines = lines;
  source.line = lines.slice(numLinesAround-1, numLinesAround)[0] || lines[0];
  return source;
}

{'fraction_non_alphanumeric': 0.14599824098504838, 'fraction_numerical': 0.002638522427440633, 'mean_word_length': 4.123123123123123, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '5875526', 'n_tokens_mistral': 1103, 'n_tokens_neox': 1092, 'n_words': 256}