You've already forked objdiff-web
mirror of
https://github.com/encounter/objdiff-web.git
synced 2026-03-30 11:32:18 -07:00
285 lines
7.7 KiB
TypeScript
285 lines
7.7 KiB
TypeScript
export const DEFAULT_WATCH_PATTERNS = [
|
|
'*.c',
|
|
'*.cp',
|
|
'*.cpp',
|
|
'*.cxx',
|
|
'*.h',
|
|
'*.hp',
|
|
'*.hpp',
|
|
'*.hxx',
|
|
'*.s',
|
|
'*.S',
|
|
'*.asm',
|
|
'*.inc',
|
|
'*.py',
|
|
'*.yml',
|
|
'*.txt',
|
|
'*.json',
|
|
];
|
|
|
|
export const CONFIG_FILENAME = 'objdiff.json';
|
|
|
|
/**
|
|
* Configuration file for objdiff
|
|
*/
|
|
export interface ProjectConfig {
|
|
/**
|
|
* Minimum version of objdiff required to load this configuration file.
|
|
*/
|
|
min_version?: string;
|
|
/**
|
|
* By default, objdiff will use make to build the project.
|
|
* If the project uses a different build system (e.g. ninja), specify it here.
|
|
* The build command will be `[custom_make] [custom_args] path/to/object.o`.
|
|
*/
|
|
custom_make?: string;
|
|
/**
|
|
* Additional arguments to pass to the build command prior to the object path.
|
|
*/
|
|
custom_args?: string[];
|
|
/**
|
|
* Relative from the root of the project, this where the "target" or "expected" objects are located.
|
|
* These are the intended result of the match.
|
|
*/
|
|
target_dir?: string;
|
|
/**
|
|
* Relative from the root of the project, this is where the "base" or "actual" objects are located.
|
|
* These are objects built from the current source code.
|
|
*/
|
|
base_dir?: string;
|
|
/**
|
|
* If true, objdiff will tell the build system to build the target objects before diffing (e.g. `make path/to/target.o`).
|
|
* This is useful if the target objects are not built by default or can change based on project configuration or edits to assembly files.
|
|
* Requires the build system to be configured properly.
|
|
*/
|
|
build_target?: boolean;
|
|
/**
|
|
* If true, objdiff will tell the build system to build the base objects before diffing (e.g. `make path/to/base.o`).
|
|
* It's unlikely you'll want to disable this, unless you're using an external tool to rebuild the base object on source file changes.
|
|
*/
|
|
build_base?: boolean;
|
|
/**
|
|
* List of glob patterns to watch for changes in the project.
|
|
* If any of these files change, objdiff will automatically rebuild the objects and re-compare them.
|
|
* Supported syntax: https://docs.rs/globset/latest/globset/#syntax
|
|
*/
|
|
watch_patterns?: string[];
|
|
/**
|
|
* Use units instead.
|
|
*/
|
|
objects?: Unit[];
|
|
/**
|
|
* If specified, objdiff will display a list of objects in the sidebar for easy navigation.
|
|
*/
|
|
units?: Unit[];
|
|
/**
|
|
* Progress categories used for objdiff-cli report.
|
|
*/
|
|
progress_categories?: ProgressCategory[];
|
|
}
|
|
export interface Unit {
|
|
/**
|
|
* The name of the object in the UI. If not specified, the object's path will be used.
|
|
*/
|
|
name?: string;
|
|
/**
|
|
* Relative path to the object from the target_dir and base_dir.
|
|
* Requires target_dir and base_dir to be specified.
|
|
*/
|
|
path?: string;
|
|
/**
|
|
* Path to the target object from the project root.
|
|
* Required if path is not specified.
|
|
*/
|
|
target_path?: string;
|
|
/**
|
|
* Path to the base object from the project root.
|
|
* Required if path is not specified.
|
|
*/
|
|
base_path?: string;
|
|
/**
|
|
* Displays function symbols in reversed order.
|
|
* Used to support MWCC's -inline deferred option, which reverses the order of functions in the object file.
|
|
*/
|
|
reverse_fn_order?: boolean;
|
|
/**
|
|
* Marks the object as "complete" (or "linked") in the object list.
|
|
* This is useful for marking objects that are fully decompiled. A value of `false` will mark the object as "incomplete".
|
|
*/
|
|
complete?: boolean;
|
|
/**
|
|
* If present, objdiff will display a button to create a decomp.me scratch.
|
|
*/
|
|
scratch?: Scratch;
|
|
/**
|
|
* Metadata for the object.
|
|
*/
|
|
metadata?: Metadata;
|
|
/**
|
|
* Manual symbol mappings from target to base.
|
|
*/
|
|
symbol_mappings?: {
|
|
[k: string]: string;
|
|
};
|
|
}
|
|
export interface Scratch {
|
|
/**
|
|
* The decomp.me platform ID to use for the scratch.
|
|
*/
|
|
platform?: string;
|
|
/**
|
|
* The decomp.me compiler ID to use for the scratch.
|
|
*/
|
|
compiler?: string;
|
|
/**
|
|
* C flags to use for the scratch. Exclude any include paths.
|
|
*/
|
|
c_flags?: string;
|
|
/**
|
|
* Path to the context file to use for the scratch.
|
|
*/
|
|
ctx_path?: string;
|
|
/**
|
|
* If true, objdiff will run the build command with the context file as an argument to generate it.
|
|
*/
|
|
build_ctx?: boolean;
|
|
}
|
|
export interface Metadata {
|
|
/**
|
|
* Marks the object as "complete" (or "linked") in the object list.
|
|
* This is useful for marking objects that are fully decompiled. A value of `false` will mark the object as "incomplete".
|
|
*/
|
|
complete?: boolean;
|
|
/**
|
|
* Displays function symbols in reversed order.
|
|
* Used to support MWCC's -inline deferred option, which reverses the order of functions in the object file.
|
|
*/
|
|
reverse_fn_order?: boolean;
|
|
/**
|
|
* Path to the source file that generated the object.
|
|
*/
|
|
source_path?: string;
|
|
/**
|
|
* Progress categories used for objdiff-cli report.
|
|
*/
|
|
progress_categories?: string[];
|
|
/**
|
|
* Hides the object from the object list by default, but still includes it in reports.
|
|
*/
|
|
auto_generated?: boolean;
|
|
}
|
|
export interface ProgressCategory {
|
|
/**
|
|
* Unique identifier for the category.
|
|
*/
|
|
id?: string;
|
|
/**
|
|
* Human-readable name of the category.
|
|
*/
|
|
name?: string;
|
|
}
|
|
|
|
export function resolveProjectConfig(config: ProjectConfig) {
|
|
if (config.watch_patterns === undefined) {
|
|
config.watch_patterns = DEFAULT_WATCH_PATTERNS;
|
|
}
|
|
if (config.build_target === undefined) {
|
|
config.build_target = false;
|
|
}
|
|
if (config.build_base === undefined) {
|
|
config.build_base = true;
|
|
}
|
|
if (config.units === undefined) {
|
|
config.units = config.objects || [];
|
|
}
|
|
for (const unit of config.units || []) {
|
|
unit.name = unit.name || unit.path || '<unnamed>';
|
|
if (unit.path) {
|
|
if (config.target_dir && !unit.target_path) {
|
|
unit.target_path = `${config.target_dir}/${unit.path}`;
|
|
}
|
|
if (config.base_dir && !unit.base_path) {
|
|
unit.base_path = `${config.base_dir}/${unit.path}`;
|
|
}
|
|
}
|
|
unit.metadata = unit.metadata || {};
|
|
if (unit.complete !== undefined && unit.metadata.complete === undefined) {
|
|
unit.metadata.complete = unit.complete;
|
|
}
|
|
if (
|
|
unit.reverse_fn_order !== undefined &&
|
|
unit.metadata.reverse_fn_order === undefined
|
|
) {
|
|
unit.metadata.reverse_fn_order = unit.reverse_fn_order;
|
|
}
|
|
}
|
|
return config;
|
|
}
|
|
|
|
export type ConfigPropertyBase = {
|
|
id: string;
|
|
name: string;
|
|
description?: string;
|
|
default: ConfigPropertyValue;
|
|
};
|
|
|
|
export type ConfigPropertyValue = boolean | string;
|
|
|
|
export type ConfigProperties = Record<string, ConfigPropertyValue>;
|
|
|
|
export type ConfigPropertyBoolean = ConfigPropertyBase & {
|
|
type: 'boolean';
|
|
default: boolean;
|
|
};
|
|
|
|
export type ConfigPropertyChoice = ConfigPropertyBase & {
|
|
type: 'choice';
|
|
default: string;
|
|
items: ConfigPropertyChoiceItem[];
|
|
};
|
|
|
|
export type ConfigProperty = ConfigPropertyBoolean | ConfigPropertyChoice;
|
|
|
|
export type ConfigPropertyChoiceItem = {
|
|
value: string;
|
|
name: string;
|
|
description?: string;
|
|
};
|
|
|
|
export type ConfigGroup = {
|
|
id: string;
|
|
name: string;
|
|
properties: string[];
|
|
};
|
|
|
|
export type ConfigSchema = {
|
|
properties: ConfigProperty[];
|
|
groups: ConfigGroup[];
|
|
};
|
|
|
|
import configSchema from 'objdiff-wasm/dist/config-schema.json';
|
|
export const CONFIG_SCHEMA = configSchema as ConfigSchema;
|
|
|
|
export function getPropertyValue(
|
|
properties: ConfigProperties,
|
|
id: string,
|
|
): ConfigPropertyValue {
|
|
const property = CONFIG_SCHEMA.properties.find((p) => p.id === id);
|
|
if (!property) {
|
|
throw new Error(`Property not found: ${id}`);
|
|
}
|
|
return properties[id] ?? property.default;
|
|
}
|
|
|
|
export function getModifiedConfigProperties(
|
|
properties: ConfigProperties,
|
|
): ConfigProperties {
|
|
const modified: ConfigProperties = {};
|
|
for (const property of CONFIG_SCHEMA.properties) {
|
|
if (property.default !== properties[property.id]) {
|
|
modified[property.id] = properties[property.id];
|
|
}
|
|
}
|
|
return modified;
|
|
}
|