Skip to content

Commit

Permalink
Merge pull request #255 from DaveMcEwan/api
Browse files Browse the repository at this point in the history
Feature: Update plugin API.
  • Loading branch information
dalance authored Jun 23, 2023
2 parents 4791906 + 420845b commit 5713c23
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 25 deletions.
77 changes: 66 additions & 11 deletions src/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,33 @@ use std::collections::HashMap;
use std::path::{Path, PathBuf};
use sv_parser::{unwrap_locate, Locate, NodeEvent, RefNode, SyntaxTree};

// Rule enum is for use by plugins.
#[derive(Clone, Copy)]
pub enum Rule {
Text(*mut dyn TextRule),
Syntax(*mut dyn SyntaxRule),
}

// Macro for use within plugins.
// Example usage in a plugin's `get_plugin` function:
// pluginrules!(
// SamplePlugin,
// AnotherPlugin,
// )
#[macro_export]
macro_rules! pluginrules {
( $( $x:ty ),* $(,)? ) => {
{
let mut vec: Vec<Rule> = Vec::new();
$(
let rule = <$x>::default();
vec.push(rule.into_rule());
)*
vec
}
};
}

#[derive(Clone, Copy)]
pub enum TextRuleResult {
Pass,
Expand All @@ -23,6 +50,14 @@ pub trait TextRule: Sync + Send {
fn name(&self) -> String;
fn hint(&self, config: &ConfigOption) -> String;
fn reason(&self) -> String;

fn into_rule(self) -> Rule
where
Self: Sized + 'static,
{
let temp = Box::new(self);
Rule::Text(Box::into_raw(temp))
}
}

#[derive(Clone, Copy)]
Expand All @@ -43,6 +78,14 @@ pub trait SyntaxRule: Sync + Send {
fn name(&self) -> String;
fn hint(&self, config: &ConfigOption) -> String;
fn reason(&self) -> String;

fn into_rule(self) -> Rule
where
Self: Sized + 'static,
{
let temp = Box::new(self);
Rule::Syntax(Box::into_raw(temp))
}
}

pub struct Linter {
Expand Down Expand Up @@ -86,20 +129,32 @@ impl Linter {
}
}

pub fn load(&mut self, path: &Path) {
let lib = unsafe { Library::new(path) };
if let Ok(lib) = lib {
self.plugins.push(lib);
let lib = self.plugins.last().unwrap();
pub fn load(&mut self, path: &Path) -> Result<(), libloading::Error> {
let lib = unsafe { Library::new(path) }?;

let get_plugin: Result<Symbol<extern "C" fn() -> *mut dyn SyntaxRule>, _> =
unsafe { lib.get(b"get_plugin") };
if let Ok(get_plugin) = get_plugin {
let plugin = unsafe { Box::from_raw(get_plugin()) };
self.ctl_enabled.insert(plugin.name(), true);
self.syntaxrules.push(plugin);
self.plugins.push(lib);
let lib = self.plugins.last().unwrap();

let get_plugin: Result<Symbol<extern "C" fn() -> Vec<Rule>>, _> =
unsafe { lib.get(b"get_plugin") };
if let Ok(get_plugin) = get_plugin {
let plugins = get_plugin();
for plugin in plugins {
match plugin {
Rule::Text(p) => {
let plugin = unsafe { Box::from_raw(p) };
self.textrules.push(plugin);
},
Rule::Syntax(p) => {
let plugin = unsafe { Box::from_raw(p) };
self.ctl_enabled.insert(plugin.name(), true);
self.syntaxrules.push(plugin);
},
}
}
}

Ok(())
}

pub fn textrules_check(&mut self, line: &str, path: &Path, beg: &usize) -> Vec<LintFailed> {
Expand Down
31 changes: 17 additions & 14 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,18 @@ pub fn run_opt(printer: &mut Printer, opt: &Opt) -> Result<bool, Error> {
_ => true,
};

if !opt.silent && !do_dump_filelist && !opt.preprocess_only {
let msg = format!(
"Config file '{}' is not found. Enable all rules",
opt.config.to_string_lossy()
);
printer.print_warning(&msg)?;
if !opt.plugins.is_empty() {
Config::new()
} else {
if !opt.silent && !do_dump_filelist && !opt.preprocess_only {
let msg = format!(
"Config file '{}' is not found. Enable all rules",
opt.config.to_string_lossy()
);
printer.print_warning(&msg)?;
}
Config::new().enable_all()
}
Config::new().enable_all()
};

run_opt_config(printer, opt, config)
Expand All @@ -198,7 +202,7 @@ pub fn run_opt_config(printer: &mut Printer, opt: &Opt, config: Config) -> Resul

let mut linter = Linter::new(config);
for plugin in &opt.plugins {
linter.load(&plugin);
linter.load(&plugin)?;
}

let mut defines = HashMap::new();
Expand Down Expand Up @@ -267,17 +271,16 @@ pub fn run_opt_config(printer: &mut Printer, opt: &Opt, config: Config) -> Resul
let text: String = read_to_string(&path)?;

let mut beg: usize = 0;
for line in text.lines() {
for failed in linter.textrules_check(&line, &path, &beg) {
for line in text.split_inclusive('\n') {
let line_stripped = line.trim_end_matches(&['\n', '\r']);

for failed in linter.textrules_check(&line_stripped, &path, &beg) {
pass = false;
if !opt.silent {
printer.print_failed(&failed, opt.single, opt.github_actions)?;
}
}

// Newlines are not included in each line and `text` does not
// contain CRLF because `read_to_string` convents CRLF to LF.
beg += line.len() + 1; // Track the beginning byte index.
beg += line.len();
}

match parse_sv_str(text.as_str(), &path, &defines, &includes, opt.ignore_include, false) {
Expand Down

0 comments on commit 5713c23

Please sign in to comment.