From 92caea8c0e61ec01346e512eccc44723c82f1d2b Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Fri, 26 Mar 2021 20:38:17 -0600 Subject: implement builtins in the worst imaginable way --- src/args.rs | 4 -- src/makefile/mod.rs | 123 +++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 117 insertions(+), 10 deletions(-) diff --git a/src/args.rs b/src/args.rs index babd7a0..41ff4f0 100644 --- a/src/args.rs +++ b/src/args.rs @@ -130,10 +130,6 @@ impl Args { .chain(env_makeflags.into_iter()) .chain(args); - let args = args.collect::>(); - dbg!(&args); - let args = args.into_iter(); - Args::from_iter(args) } diff --git a/src/makefile/mod.rs b/src/makefile/mod.rs index e8adac9..2959953 100644 --- a/src/makefile/mod.rs +++ b/src/makefile/mod.rs @@ -17,7 +17,7 @@ mod token; use token::{tokenize, Token, TokenString}; -#[derive(PartialEq, Eq, Clone)] +#[derive(PartialEq, Eq, Clone, Debug)] pub struct InferenceRule { /// POSIX calls this ".s1" but that's not useful. product: String, @@ -104,7 +104,7 @@ impl fmt::Display for Target { } } -#[derive(PartialEq, Eq, Clone)] +#[derive(PartialEq, Eq, Clone, Debug)] pub struct CommandLine { /// If the command prefix contains a , or the -i option is present, or /// the special target .IGNORE has either the current target as a prerequisite or has @@ -204,7 +204,7 @@ impl fmt::Display for CommandLine { } let execution_line = format!("{}", &self.execution_line); let execution_line = execution_line.replace("\n", "↵\n"); - writeln!(f, "{}", execution_line)?; + write!(f, "{}", execution_line)?; Ok(()) } } @@ -727,11 +727,122 @@ impl fmt::Display for Makefile { } fn builtin_inference_rules() -> Vec { - todo!() + // This is a terrible idea. + macro_rules! prepend_dot { + ($x:tt) => {concat!(".", stringify!($x))}; + () => {""}; + } + + macro_rules! make { + {$(.$first:tt$(.$second:tt)?: + $($cmd:literal)+)+} => { + vec![$( + InferenceRule { + product: prepend_dot!($($second)?).into(), + prereq: concat!(".", stringify!($first)).into(), + commands: vec![$(CommandLine::from($cmd.parse().unwrap())),+], + } + ),+] + }; + } + + make! { + .c: + "$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<" + .f: + "$(FC) $(FFLAGS) $(LDFLAGS) -o $@ $<" + .sh: + "cp $< $@" + "chmod a+x $@" + + .c.o: + "$(CC) $(CFLAGS) -c $<" + .f.o: + "$(FC) $(FFLAGS) -c $<" + .y.o: + "$(YACC) $(YFLAGS) $<" + "$(CC) $(CFLAGS) -c y.tab.c" + "rm -f y.tab.c" + "mv y.tab.o $@" + .l.o: + "$(LEX) $(LFLAGS) $<" + "$(CC) $(CFLAGS) -c lex.yy.c" + "rm -f lex.yy.c" + "mv lex.yy.o $@" + .y.c: + "$(YACC) $(YFLAGS) $<" + "mv y.tab.c $@" + .l.c: + "$(LEX) $(LFLAGS) $<" + "mv lex.yy.c $@" + .c.a: + "$(CC) -c $(CFLAGS) $<" + "$(AR) $(ARFLAGS) $@ $*.o" + "rm -f $*.o" + .f.a: + "$(FC) -c $(FFLAGS) $<" + "$(AR) $(ARFLAGS) $@ $*.o" + "rm -f $*.o" + } } fn builtin_macros() -> Vec<(&'static str, TokenString)> { - todo!() + // Fuck it, might as well. + macro_rules! handle { + ($value:ident) => {stringify!($value)}; + ($value:literal) => {$value}; + } + macro_rules! make { + ($($name:ident=$value:tt)+) => {vec![$( + (stringify!($name), handle!($value).parse().unwrap()) + ),+]}; + } + + make![ + MAKE=makers + AR=ar + YACC=yacc + YFLAGS="" + LEX=lex + LFLAGS="" + LDFLAGS="" + + AS=as + CC=cc + CXX="g++" + CPP="$(CC) -E" + FC=f77 + PC=pc + CO=co + GET=get + LINT=lint + MAKEINFO=makeinfo + TEX=tex + TEXI2DVI=texi2dvi + WEAVE=weave + CWEAVE=cweave + TANGLE=tangle + CTANGLE=ctangle + RM="rm -f" + + ARFLAGS="rv" + CFLAGS="" + FFLAGS="" + ] } fn builtin_targets() -> Vec { - todo!() + // even i'm not going to do that just for this + vec![ + Target { + name: ".SUFFIXES".into(), + prerequisites: vec![".o", ".c", ".y", ".l", ".a", ".sh", ".f"].into_iter().map(String::from).collect(), + commands: vec![], + already_updated: Cell::new(false), + } + ] +} + +#[cfg(test)] +mod test { + use super::*; + } -- cgit v1.2.3