<commit_before>package processing.app;

import cc.arduino.Compiler;
import cc.arduino.Constants;
import cc.arduino.UploaderUtils;
import cc.arduino.contributions.GPGDetachedSignatureVerifier;
import cc.arduino.contributions.SignatureVerificationFailedException;
import cc.arduino.contributions.VersionComparator;
import cc.arduino.contributions.libraries.LibrariesIndexer;
import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.contributions.packages.ContributedTool;
import cc.arduino.contributions.packages.ContributionsIndexer;
import cc.arduino.files.DeleteFilesOnShutdown;
import cc.arduino.packages.DiscoveryManager;
import cc.arduino.packages.Uploader;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.logging.impl.LogFactoryImpl;
import org.apache.commons.logging.impl.NoOpLog;
import processing.app.debug.*;
import processing.app.helpers.*;
import processing.app.helpers.filefilters.OnlyDirs;
import processing.app.helpers.filefilters.OnlyFilesWithExtension;
import processing.app.legacy.PApplet;
import processing.app.packages.LibraryList;
import processing.app.packages.UserLibrary;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

import cc.arduino.packages.BoardPort;

import static processing.app.I18n.tr;
import static processing.app.helpers.filefilters.OnlyDirs.ONLY_DIRS;

public class BaseNoGui {

  /** Version string to be used for build */
  public static final int REVISION = 10613;
  /** Extended version string displayed on GUI */
  public static final String VERSION_NAME = "1.6.13";
  public static final String VERSION_NAME_LONG;

  // Current directory to use for relative paths specified on the
  // commandline
  static String currentDirectory = System.getProperty("user.dir");

  static {
    String versionNameLong = VERSION_NAME;
    File hourlyBuildTxt = new File(getContentFile("lib"), "hourlyBuild.txt");
    if (hourlyBuildTxt.exists() && hourlyBuildTxt.canRead()) {
      versionNameLong += " Hourly Build";
      try {
        versionNameLong += " " + FileUtils.readFileToString(hourlyBuildTxt).trim();
      } catch (IOException e) {
        //noop
      }
    }
    VERSION_NAME_LONG = versionNameLong;
  }

  private static DiscoveryManager discoveryManager;

  // these are static because they're used by Sketch
  static private File examplesFolder;
  static private File toolsFolder;

  // maps #included files to their library folder
  public static Map<String, LibraryList> importToLibraryTable;

  // XXX: Remove this field
  static private List<File> librariesFolders;

  static UserNotifier notifier = new BasicUserNotifier();

  static public Map<String, TargetPackage> packages;

  static Platform platform;

  static File portableFolder = null;
  static final String portableSketchbookFolder = "sketchbook";

  public static ContributionsIndexer indexer;
  public static LibrariesIndexer librariesIndexer;

  private static String boardManagerLink = "";

  // Returns a File object for the given pathname. If the pathname
  // is not absolute, it is interpreted relative to the current
  // directory when starting the IDE (which is not the same as the
  // current working directory!).
  static public File absoluteFile(String path) {
    if (path == null) return null;

    File file = new File(path);
    if (!file.isAbsolute()) {
      file = new File(currentDirectory, path);
    }
    return file;
  }

  /**
   * Get the number of lines in a file by counting the number of newline
   * characters inside a String (and adding 1).
   */
  static public int countLines(String what) {
    int count = 1;
    for (char c : what.toCharArray()) {
      if (c == '\n') count++;
    }
    return count;
  }

  static public String getAvrBasePath() {
    String path = getHardwarePath() + File.separator + "tools" +
                  File.separator + "avr" + File.separator + "bin" + File.separator;
    if (OSUtils.isLinux() && !(new File(path)).exists()) {
      return "";  // use distribution provided avr tools if bundled tools missing
    }
    return path;
  }

  static public PreferencesMap getBoardPreferences() {
    TargetBoard board = getTargetBoard();
    if (board == null)
      return null;
    String boardId = board.getId();
    
    PreferencesMap prefs = new PreferencesMap(board.getPreferences());

    String extendedName = prefs.get("name");
    for (String menuId : board.getMenuIds()) {
      if (!board.hasMenu(menuId))
        continue;

      // Get "custom_[MENU_ID]" preference (for example "custom_cpu")
      String entry = PreferencesData.get("custom_" + menuId);
      if (entry != null && entry.startsWith(boardId)) {

        String selectionId = entry.substring(boardId.length() + 1);
        prefs.putAll(board.getMenuPreferences(menuId, selectionId));

        // Update the name with the extended configuration
        extendedName += ", " + board.getMenuLabel(menuId, selectionId);
      }
    }
    prefs.put("name", extendedName);

    // Resolve tools needed for this board
    List<ContributedTool> requiredTools = new ArrayList<>();

    // Add all tools dependencies specified in package index
    ContributedPlatform platform = indexer.getContributedPlaform(getTargetPlatform());
    if (platform != null)
      requiredTools.addAll(platform.getResolvedTools());

    // Add all tools dependencies from the (possibily) referenced core
    String core = prefs.get("build.core");
    if (core.contains(":")) {
      String split[] = core.split(":");
      TargetPlatform referenced = BaseNoGui.getCurrentTargetPlatformFromPackage(split[0]);
      ContributedPlatform referencedPlatform = indexer.getContributedPlaform(referenced);
      if (referencedPlatform != null)
        requiredTools.addAll(referencedPlatform.getResolvedTools());
    }
<commit_msg>Fix NPE if referred core is nonexistent<commit_after>package processing.app;

import cc.arduino.Compiler;
import cc.arduino.Constants;
import cc.arduino.UploaderUtils;
import cc.arduino.contributions.GPGDetachedSignatureVerifier;
import cc.arduino.contributions.SignatureVerificationFailedException;
import cc.arduino.contributions.VersionComparator;
import cc.arduino.contributions.libraries.LibrariesIndexer;
import cc.arduino.contributions.packages.ContributedPlatform;
import cc.arduino.contributions.packages.ContributedTool;
import cc.arduino.contributions.packages.ContributionsIndexer;
import cc.arduino.files.DeleteFilesOnShutdown;
import cc.arduino.packages.DiscoveryManager;
import cc.arduino.packages.Uploader;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.logging.impl.LogFactoryImpl;
import org.apache.commons.logging.impl.NoOpLog;
import processing.app.debug.*;
import processing.app.helpers.*;
import processing.app.helpers.filefilters.OnlyDirs;
import processing.app.helpers.filefilters.OnlyFilesWithExtension;
import processing.app.legacy.PApplet;
import processing.app.packages.LibraryList;
import processing.app.packages.UserLibrary;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

import cc.arduino.packages.BoardPort;

import static processing.app.I18n.tr;
import static processing.app.helpers.filefilters.OnlyDirs.ONLY_DIRS;

public class BaseNoGui {

  /** Version string to be used for build */
  public static final int REVISION = 10613;
  /** Extended version string displayed on GUI */
  public static final String VERSION_NAME = "1.6.13";
  public static final String VERSION_NAME_LONG;

  // Current directory to use for relative paths specified on the
  // commandline
  static String currentDirectory = System.getProperty("user.dir");

  static {
    String versionNameLong = VERSION_NAME;
    File hourlyBuildTxt = new File(getContentFile("lib"), "hourlyBuild.txt");
    if (hourlyBuildTxt.exists() && hourlyBuildTxt.canRead()) {
      versionNameLong += " Hourly Build";
      try {
        versionNameLong += " " + FileUtils.readFileToString(hourlyBuildTxt).trim();
      } catch (IOException e) {
        //noop
      }
    }
    VERSION_NAME_LONG = versionNameLong;
  }

  private static DiscoveryManager discoveryManager;

  // these are static because they're used by Sketch
  static private File examplesFolder;
  static private File toolsFolder;

  // maps #included files to their library folder
  public static Map<String, LibraryList> importToLibraryTable;

  // XXX: Remove this field
  static private List<File> librariesFolders;

  static UserNotifier notifier = new BasicUserNotifier();

  static public Map<String, TargetPackage> packages;

  static Platform platform;

  static File portableFolder = null;
  static final String portableSketchbookFolder = "sketchbook";

  public static ContributionsIndexer indexer;
  public static LibrariesIndexer librariesIndexer;

  private static String boardManagerLink = "";

  // Returns a File object for the given pathname. If the pathname
  // is not absolute, it is interpreted relative to the current
  // directory when starting the IDE (which is not the same as the
  // current working directory!).
  static public File absoluteFile(String path) {
    if (path == null) return null;

    File file = new File(path);
    if (!file.isAbsolute()) {
      file = new File(currentDirectory, path);
    }
    return file;
  }

  /**
   * Get the number of lines in a file by counting the number of newline
   * characters inside a String (and adding 1).
   */
  static public int countLines(String what) {
    int count = 1;
    for (char c : what.toCharArray()) {
      if (c == '\n') count++;
    }
    return count;
  }

  static public String getAvrBasePath() {
    String path = getHardwarePath() + File.separator + "tools" +
                  File.separator + "avr" + File.separator + "bin" + File.separator;
    if (OSUtils.isLinux() && !(new File(path)).exists()) {
      return "";  // use distribution provided avr tools if bundled tools missing
    }
    return path;
  }

  static public PreferencesMap getBoardPreferences() {
    TargetBoard board = getTargetBoard();
    if (board == null)
      return null;
    String boardId = board.getId();
    
    PreferencesMap prefs = new PreferencesMap(board.getPreferences());

    String extendedName = prefs.get("name");
    for (String menuId : board.getMenuIds()) {
      if (!board.hasMenu(menuId))
        continue;

      // Get "custom_[MENU_ID]" preference (for example "custom_cpu")
      String entry = PreferencesData.get("custom_" + menuId);
      if (entry != null && entry.startsWith(boardId)) {

        String selectionId = entry.substring(boardId.length() + 1);
        prefs.putAll(board.getMenuPreferences(menuId, selectionId));

        // Update the name with the extended configuration
        extendedName += ", " + board.getMenuLabel(menuId, selectionId);
      }
    }
    prefs.put("name", extendedName);

    // Resolve tools needed for this board
    List<ContributedTool> requiredTools = new ArrayList<>();

    // Add all tools dependencies specified in package index
    ContributedPlatform platform = indexer.getContributedPlaform(getTargetPlatform());
    if (platform != null)
      requiredTools.addAll(platform.getResolvedTools());

    // Add all tools dependencies from the (possibily) referenced core
    String core = prefs.get("build.core");
    if (core != null && core.contains(":")) {
      String split[] = core.split(":");
      TargetPlatform referenced = BaseNoGui.getCurrentTargetPlatformFromPackage(split[0]);
      if (referenced != null) {
        ContributedPlatform referencedPlatform = indexer.getContributedPlaform(referenced);
        if (referencedPlatform != null)
          requiredTools.addAll(referencedPlatform.getResolvedTools());
      }
    }

{'fraction_non_alphanumeric': 0.0994429882044561, 'fraction_numerical': 0.0024574049803407602, 'mean_word_length': 3.9529411764705884, 'pattern_counts': {'":': 4, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '2003704', 'n_tokens_mistral': 3495, 'n_tokens_neox': 3369, 'n_words': 931}