<commit_before>//===- Reproduce.cpp - Utilities for creating reproducers -----------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lld/Core/Reproduce.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Option/Arg.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"

using namespace lld;
using namespace llvm;
using namespace sys;

CpioFile::CpioFile(std::unique_ptr<raw_fd_ostream> OS, StringRef S)
    : OS(std::move(OS)), Basename(S) {}

ErrorOr<CpioFile *> CpioFile::create(StringRef OutputPath) {
  std::string Path = (OutputPath + ".cpio").str();
  std::error_code EC;
  auto OS = llvm::make_unique<raw_fd_ostream>(Path, EC, sys::fs::F_None);
  if (EC)
    return EC;
  return new CpioFile(std::move(OS), path::filename(OutputPath));
}

static void writeMember(raw_fd_ostream &OS, StringRef Path, StringRef Data) {
  // The c_dev/c_ino pair should be unique according to the spec,
  // but no one seems to care.
  OS << "070707";                        // c_magic
  OS << "000000";                        // c_dev
  OS << "000000";                        // c_ino
  OS << "100664";                        // c_mode: C_ISREG | rw-rw-r--
  OS << "000000";                        // c_uid
  OS << "000000";                        // c_gid
  OS << "000001";                        // c_nlink
  OS << "000000";                        // c_rdev
  OS << "00000000000";                   // c_mtime
  OS << format("%06o", Path.size() + 1); // c_namesize
  OS << format("%011o", Data.size());    // c_filesize
  OS << Path << '\0';                    // c_name
  OS << Data;                            // c_filedata
}

// Converts path to use unix path separators so the cpio can be extracted on
// both unix and windows.
static void convertToUnixPathSeparator(SmallString<128> &Path) {
  std::replace(Path.begin(), Path.end(), '\\', '/');
}

void CpioFile::append(StringRef Path, StringRef Data) {
  if (!Seen.insert(Path).second)
    return;

  // Construct an in-archive filename so that /home/foo/bar is stored
  // as baz/home/foo/bar where baz is the basename of the output file.
  // (i.e. in that case we are creating baz.cpio.)
  SmallString<128> Fullpath;
  path::append(Fullpath, Basename, Path);
  convertToUnixPathSeparator(Fullpath);

  writeMember(*OS, Fullpath, Data);

  // Print the trailer and seek back.
  // This way we have a valid archive if we crash.
  uint64_t Pos = OS->tell();
  writeMember(*OS, "TRAILER!!!", "");
  OS->seek(Pos);
}

// Makes a given pathname an absolute path first, and then remove
// beginning /. For example, "../foo.o" is converted to "home/john/foo.o",
// assuming that the current directory is "/home/john/bar".
// Returned string is a backslash-separated path even on Windows to avoid
// a mess with backslash-as-escape and backslash-as-path-separator.
std::string lld::relativeToRoot(StringRef Path) {
  SmallString<128> Abs = Path;
  if (sys::fs::make_absolute(Abs))
    return Path;
  path::remove_dots(Abs, /*remove_dot_dot=*/true);

  // This is Windows specific. root_name() returns a drive letter
  // (e.g. "c:") or a UNC name (//net). We want to keep it as part
  // of the result.
  SmallString<128> Res;
  StringRef Root = path::root_name(Abs);
  if (Root.endswith(":"))
    Res = Root.drop_back();
  else if (Root.startswith("//"))
    Res = Root.substr(2);

  path::append(Res, path::relative_path(Abs));
  convertToUnixPathSeparator(Res);
<commit_msg>[ELF] - Fixed comment. NFC.<commit_after>//===- Reproduce.cpp - Utilities for creating reproducers -----------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lld/Core/Reproduce.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Option/Arg.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/Path.h"

using namespace lld;
using namespace llvm;
using namespace sys;

CpioFile::CpioFile(std::unique_ptr<raw_fd_ostream> OS, StringRef S)
    : OS(std::move(OS)), Basename(S) {}

ErrorOr<CpioFile *> CpioFile::create(StringRef OutputPath) {
  std::string Path = (OutputPath + ".cpio").str();
  std::error_code EC;
  auto OS = llvm::make_unique<raw_fd_ostream>(Path, EC, sys::fs::F_None);
  if (EC)
    return EC;
  return new CpioFile(std::move(OS), path::filename(OutputPath));
}

static void writeMember(raw_fd_ostream &OS, StringRef Path, StringRef Data) {
  // The c_dev/c_ino pair should be unique according to the spec,
  // but no one seems to care.
  OS << "070707";                        // c_magic
  OS << "000000";                        // c_dev
  OS << "000000";                        // c_ino
  OS << "100664";                        // c_mode: C_ISREG | rw-rw-r--
  OS << "000000";                        // c_uid
  OS << "000000";                        // c_gid
  OS << "000001";                        // c_nlink
  OS << "000000";                        // c_rdev
  OS << "00000000000";                   // c_mtime
  OS << format("%06o", Path.size() + 1); // c_namesize
  OS << format("%011o", Data.size());    // c_filesize
  OS << Path << '\0';                    // c_name
  OS << Data;                            // c_filedata
}

// Converts path to use unix path separators so the cpio can be extracted on
// both unix and windows.
static void convertToUnixPathSeparator(SmallString<128> &Path) {
  std::replace(Path.begin(), Path.end(), '\\', '/');
}

void CpioFile::append(StringRef Path, StringRef Data) {
  if (!Seen.insert(Path).second)
    return;

  // Construct an in-archive filename so that /home/foo/bar is stored
  // as baz/home/foo/bar where baz is the basename of the output file.
  // (i.e. in that case we are creating baz.cpio.)
  SmallString<128> Fullpath;
  path::append(Fullpath, Basename, Path);
  convertToUnixPathSeparator(Fullpath);

  writeMember(*OS, Fullpath, Data);

  // Print the trailer and seek back.
  // This way we have a valid archive if we crash.
  uint64_t Pos = OS->tell();
  writeMember(*OS, "TRAILER!!!", "");
  OS->seek(Pos);
}

// Makes a given pathname an absolute path first, and then remove
// beginning /. For example, "../foo.o" is converted to "home/john/foo.o",
// assuming that the current directory is "/home/john/bar".
// Returned string is a forward slash separated path even on Windows to avoid
// a mess with backslash-as-escape and backslash-as-path-separator.
std::string lld::relativeToRoot(StringRef Path) {
  SmallString<128> Abs = Path;
  if (sys::fs::make_absolute(Abs))
    return Path;
  path::remove_dots(Abs, /*remove_dot_dot=*/true);

  // This is Windows specific. root_name() returns a drive letter
  // (e.g. "c:") or a UNC name (//net). We want to keep it as part
  // of the result.
  SmallString<128> Res;
  StringRef Root = path::root_name(Abs);
  if (Root.endswith(":"))
    Res = Root.drop_back();
  else if (Root.startswith("//"))
    Res = Root.substr(2);

  path::append(Res, path::relative_path(Abs));
  convertToUnixPathSeparator(Res);

{'fraction_non_alphanumeric': 0.17052407555200852, 'fraction_numerical': 0.02154828411811652, 'mean_word_length': 2.43490178163545, 'pattern_counts': {'":': 2, '<': 73, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3911788', 'n_tokens_mistral': 2546, 'n_tokens_neox': 2388, 'n_words': 677}