use std::io;
use std::env;
use std::fmt;
use std::path::PathBuf;
use fs_err as fs;
pub fn write_const<W, T>(mut w: W, name: &str, value: &T, type_name: &str) -> io::Result<()>
where
W: io::Write,
T: fmt::Debug,
{
writeln!(
w,
r###"#[allow(unused)]
pub(crate) static {}: {} = {:#?};"###,
name, type_name, value
)
}
#[allow(unused)]
fn write_field_tables<W: io::Write>(mut w: W) -> io::Result<()> {
let mut log_table: [Elt; FIELD_SIZE] = [0; FIELD_SIZE];
let mut exp_table: [Elt; FIELD_SIZE] = [0; FIELD_SIZE];
let mas: Elt = (1 << (FIELD_BITS - 1)) - 1;
let mut state: usize = 1;
for i in 0_usize..(ONEMASK as usize) {
exp_table[state] = i as Elt;
if (state >> (FIELD_BITS - 1)) != 0 {
state &= mas as usize;
state = state << 1_usize ^ GENERATOR as usize;
} else {
state <<= 1;
}
}
exp_table[0] = ONEMASK;
log_table[0] = 0;
for i in 0..FIELD_BITS {
for j in 0..(1 << i) {
log_table[j + (1 << i)] = log_table[j] ^ BASE[i];
}
}
for i in 0..FIELD_SIZE {
log_table[i] = exp_table[log_table[i] as usize];
}
for i in 0..FIELD_SIZE {
exp_table[log_table[i] as usize] = i as Elt;
}
exp_table[ONEMASK as usize] = exp_table[0];
write_const(&mut w, "LOG_TABLE", &log_table, "[Elt; FIELD_SIZE]")?;
write_const(&mut w, "EXP_TABLE", &exp_table, "[Elt; FIELD_SIZE]")?;
let log_walsh = log_table;
let mut log_walsh = unsafe { core::mem::transmute::<_, [Multiplier; FIELD_SIZE]>(log_walsh) };
log_walsh[0] = Multiplier(0);
walsh(&mut log_walsh[..], FIELD_SIZE);
write_const(w, "LOG_WALSH", &log_walsh, "[Multiplier; FIELD_SIZE]")?;
Ok(())
}
pub fn gen_field_tables() -> io::Result<()> {
println!("cargo:rustc-cfg=table_bootstrap_complete");
let out = env::var("OUT_DIR").expect("OUT_DIR is set by cargo after process launch. qed");
let path = PathBuf::from(out).join(format!("table_{}.rs", FIELD_NAME));
let f = fs::OpenOptions::new().create(true).truncate(true).write(true).open(path)?;
write_field_tables(f)?;
Ok(())
}