Skip to content

Instantly share code, notes, and snippets.

@scarf005
Created April 8, 2023 05:54
Show Gist options
  • Save scarf005/d2cc2fcfdd07c7eb4089cc19380a465c to your computer and use it in GitHub Desktop.
Save scarf005/d2cc2fcfdd07c7eb4089cc19380a465c to your computer and use it in GitHub Desktop.
import { assertEquals } from "https://deno.land/std@0.177.0/testing/asserts.ts"
import { outdent } from "npm:outdent"
import { trisection } from "./partition_utils.ts"
import { walk } from "https://deno.land/std@0.182.0/fs/walk.ts"
import { asynciter } from "https://deno.land/x/asynciter@0.0.15/asynciter.ts"
import { fromFileUrl, join, resolve } from "https://deno.land/std@0.177.0/path/mod.ts"
export const SCRIPT_DIR = fromFileUrl(import.meta.url)
export const TOP_DIR = resolve(SCRIPT_DIR, "..", "..", "..")
export const JSON_DIR = join(TOP_DIR, "data")
export const TAGS_FILE = join(TOP_DIR, "tags")
export const SRC_DIR = join(TOP_DIR, "src")
export const TEST_DIR = join(TOP_DIR, "tests")
const isSystemHeader = (line: string) => line.startsWith("#include <") && line.endsWith(">")
/** insert a header in alphabetical order without sorting the whole array. */
export const insertAlphabetically = (input: string[], newHeader: string): string[] => {
const insertIndex = input.findIndex((header) => header.localeCompare(newHeader) > 0)
return insertIndex !== -1
? [...input.slice(0, insertIndex), newHeader, ...input.slice(insertIndex)]
: [...input, newHeader]
}
Deno.test("insertAlphabetically", async (t) => {
const input = [
"#include <array>",
"#include <functional>",
"#include <memory>",
"#include <string>",
"#include <unordered_map>",
"#include <unordered_set>",
"#include <vector>",
]
const output = [
"#include <array>",
"#include <functional>",
"#include <memory>",
"#include <optional>",
"#include <string>",
"#include <unordered_map>",
"#include <unordered_set>",
"#include <vector>",
]
await t.step("insert at the middle", () => {
assertEquals(insertAlphabetically(input, "#include <optional>"), output)
})
await t.step("empty headers", () => {
assertEquals(insertAlphabetically([], "#include <optional>"), ["#include <optional>"])
})
})
const insertSystemHeader = (lines: string[], systemHeader: string): string[] => {
if (!systemHeader.startsWith("#include <") || !systemHeader.endsWith(">")) {
throw new Error("Invalid system header format.")
}
if (!lines.includes(systemHeader)) {
return lines
}
const [before, middle, after] = trisection(
lines.filter((x) => x !== systemHeader),
isSystemHeader,
)
return [...before, ...insertAlphabetically(middle, systemHeader), ...after]
}
Deno.test("insertSystemHeader", (t) => {
const input = outdent`
#ifndef CATA_SRC_ACHIEVEMENT_H
#define CATA_SRC_ACHIEVEMENT_H
#include <array>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "calendar.h"
#include "cata_variant.h"
#include "event_bus.h"
#include <optional>
#include "string_id.h"
#include "translations.h"
class JsonIn;
class JsonObject;
class JsonOut;
`
const output = outdent`
#ifndef CATA_SRC_ACHIEVEMENT_H
#define CATA_SRC_ACHIEVEMENT_H
#include <array>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "calendar.h"
#include "cata_variant.h"
#include "event_bus.h"
#include "string_id.h"
#include "translations.h"
class JsonIn;
class JsonObject;
class JsonOut;
`
const header = "#include <optional>"
const result = insertSystemHeader(input.split("\n"), header)
assertEquals(result.join("\n"), output)
})
if (import.meta.main) {
const header = "#include <optional>"
asynciter(walk(TEST_DIR, { exts: [".cpp", ".h"] }))
.concurrentUnorderedMap(async ({ path }) => {
console.log(path)
const text = await Deno.readTextFile(path)
const lines = text.split("\n")
const mapped = insertSystemHeader(lines, header)
await Deno.writeTextFile(path, mapped.join("\n"))
})
.collect()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment