Move diff_flags to its own functions, add algorithm

This commit is contained in:
Elliptic Ellipsis
2022-11-15 00:21:38 +00:00
parent f697da0212
commit 8d26e38808
5 changed files with 90 additions and 18 deletions

View File

@@ -56,6 +56,7 @@ class DiffWrapper:
arch: asm_differ.ArchSettings, diff_flags: List[str]
) -> asm_differ.Config:
show_rodata_refs = "-DIFFno_show_rodata_refs" not in diff_flags
algorithm = "difflib" if "-DIFFdifflib" in diff_flags else "levenshtein"
return asm_differ.Config(
arch=arch,
@@ -80,7 +81,7 @@ class DiffWrapper:
stop_at_ret=False,
ignore_large_imms=False,
ignore_addr_diffs=True,
algorithm="levenshtein",
algorithm=algorithm,
reg_categories={},
show_rodata_refs=show_rodata_refs,
)

View File

@@ -85,6 +85,13 @@ COMMON_IDO_FLAGS: Flags = [
Checkbox("kpic", "-KPIC"),
]
COMMON_DIFF_FLAGS: Flags = [
FlagSet(
id="diff_algorithm",
flags=[ASMDIFF_FLAG_PREFIX + "levenshtein", ASMDIFF_FLAG_PREFIX + "difflib"],
),
]
COMMON_MIPS_DIFF_FLAGS: Flags = [
Checkbox("mreg_names=32", "-Mreg-names=32"),
Checkbox("no_show_rodata_refs", ASMDIFF_FLAG_PREFIX + "no_show_rodata_refs"),

View File

@@ -2,7 +2,7 @@ import logging
from dataclasses import dataclass, field
from typing import OrderedDict
from coreapp.flags import COMMON_MIPS_DIFF_FLAGS, Flags
from coreapp.flags import COMMON_MIPS_DIFF_FLAGS, COMMON_DIFF_FLAGS, Flags
logger = logging.getLogger(__name__)
@@ -18,7 +18,7 @@ class Platform:
objdump_cmd: str
nm_cmd: str
asm_prelude: str
diff_flags: Flags = field(default_factory=list, hash=False)
diff_flags: Flags = field(default_factory=lambda: COMMON_DIFF_FLAGS, hash=False)
supports_objdump_disassemble: bool = False # TODO turn into objdump flag
@@ -59,7 +59,7 @@ N64 = Platform(
assemble_cmd='mips-linux-gnu-as -march=vr4300 -mabi=32 -o "$OUTPUT" "$INPUT"',
objdump_cmd="mips-linux-gnu-objdump",
nm_cmd="mips-linux-gnu-nm",
diff_flags=COMMON_MIPS_DIFF_FLAGS,
diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS,
asm_prelude="""
.macro .late_rodata
.section .rodata

View File

@@ -230,5 +230,9 @@
"sdata_limit.-G4": "4 bytes",
"sdata_limit.-G8": "8 bytes",
"mreg_names=32": "ABI FPR names",
"no_show_rodata_refs": "Hide rodata refs in diff, e.g. jtbl labels"
"no_show_rodata_refs": "Hide rodata refs in diff, e.g. jtbl labels",
"diff_algorithm": "Diff algorithm",
"diff_algorithm.-DIFFlevenshtein": "Levenshtein",
"diff_algorithm.-DIFFdifflib": "difflib"
}

View File

@@ -31,6 +31,18 @@ function Checkbox({ flag, description }) {
</div>
}
function DiffCheckbox({ flag, description }) {
const { checkFlag, setFlag } = useContext(OptsContext)
const isChecked = checkFlag(flag)
return <div className={styles.flag} onClick={() => setFlag(flag, !isChecked)}>
<input type="checkbox" checked={isChecked} onChange={() => setFlag(flag, !isChecked)} />
<label>{description}</label>
<span className={styles.flagDescription}>{flag}</span>
</div>
}
function FlagSet({ name, children, value }) {
const { setFlag } = useContext(OptsContext)
@@ -51,12 +63,38 @@ function FlagSet({ name, children, value }) {
</div>
}
function DiffFlagSet({ name, children, value }) {
const { setFlag } = useContext(OptsContext)
return <div className={styles.flagSet}>
<div className={styles.flagSetName}>{name}</div>
<Select
onChange={event => {
for (const child of children) {
setFlag(child.props.flag, false)
}
setFlag((event.target as HTMLSelectElement).value, true)
}}
value={value}
>
{children}
</Select>
</div>
}
function FlagOption({ flag, description }: { flag: string, description?: string }) {
return <option value={flag}>
{flag} {description && description !== NO_TRANSLATION && `(${description})`}
</option>
}
function DiffFlagOption({ flag, description }: { flag: string, description?: string }) {
return <option value={flag}>
{description || flag}
</option>
}
interface FlagsProps {
schema: api.Flag[]
}
@@ -81,6 +119,26 @@ function Flags({ schema }: FlagsProps) {
</>
}
function DiffFlags({ schema }: FlagsProps) {
const compilersTranslation = useTranslation("compilers")
const { checkFlag } = useContext(OptsContext)
return <>
{schema.map(flag => {
if (flag.type === "checkbox") {
return <DiffCheckbox key={flag.id} flag={flag.flag} description={compilersTranslation.t(flag.id)} />
} else if (flag.type === "flagset") {
const selectedFlag = flag.flags.filter(checkFlag)[0] || flag.flags[0]
return <DiffFlagSet key={flag.id} name={compilersTranslation.t(flag.id)} value={selectedFlag}>
{flag.flags.map(f => <DiffFlagOption key={f} flag={f} description={
compilersTranslation.t(flag.id + "." + f, null, { default: NO_TRANSLATION })
} />)}
</DiffFlagSet>
}
})}
</>
}
export type CompilerOptsT = {
compiler: string
compiler_flags: string
@@ -181,17 +239,7 @@ export default function CompilerOpts({ platform, value, onChange, diffLabel, onD
}}>
<section className={styles.section}>
<h3 className={styles.heading}>Diff options</h3>
<div className={styles.diffLabel}>
<label>Diff label</label>
<input
type="text"
className={styles.textbox}
value={diffLabel}
placeholder="Top of file"
onChange={e => onDiffLabelChange(e.target.value)}
/>
</div>
<DiffOptsEditor platform={platform} compiler={compiler} />
<DiffOptsEditor platform={platform} compiler={compiler} diffLabel={diffLabel} onDiffLabelChange={onDiffLabelChange} />
</section>
</OptsContext.Provider>
</div>
@@ -245,16 +293,28 @@ export function OptsEditor({ platform, compiler: compilerId, setCompiler, opts,
</div>
}
export function DiffOptsEditor({ platform, compiler: compilerId }: {
export function DiffOptsEditor({ platform, compiler: compilerId, diffLabel, onDiffLabelChange }: {
platform?: string
compiler: string
diffLabel: string
onDiffLabelChange: (diffLabel: string) => void
}) {
const compilers = useCompilersForPlatform(platform)
const compiler = compilers[compilerId]
return <div>
<div className={styles.diffLabel}>
<label>Diff label</label>
<input
type="text"
className={styles.textbox}
value={diffLabel}
placeholder="Top of file"
onChange={e => onDiffLabelChange(e.target.value)}
/>
</div>
<div className={styles.diffFlags}>
{(compilerId && compiler) ? <Flags schema={compiler.diff_flags} /> : <div />}
{(compilerId && compiler) ? <DiffFlags schema={compiler.diff_flags} /> : <div />}
</div>
</div>
}