libperl_config/
perl_config.rs1use super::process_util::*;
2
3use super::PerlCommand;
4
5use std::collections::HashMap;
6
7type ConfigDict = HashMap<String, String>;
8
9use chrono::prelude::*;
10
11pub struct PerlConfig {
12 command: PerlCommand,
13 pub dict: ConfigDict,
14}
15
16impl Default for PerlConfig {
17 fn default() -> Self {
18 let cmd = PerlCommand::default();
19 let dict = read_config(&cmd, &[]).expect("Failed to read Config.pm");
20 Self {
21 command: cmd,
22 dict: dict,
23 }
24 }
25}
26
27impl PerlConfig {
28
29 pub fn new(perl: &str) -> Self {
30 let cmd = PerlCommand::new(perl);
31 let dict = read_config(&cmd, &[]).expect("Failed to read Config.pm");
32 Self {
33 command: cmd,
34 dict: dict,
35 }
36 }
37
38 pub fn command(&self, args: &[&str]) -> Command {
39 self.command.command(args)
40 }
41
42 pub fn read_ccopts(&self) -> Result<Vec<String>, Error> {
43 self.command.read_ccopts()
44 }
45
46 pub fn read_ldopts(&self) -> Result<Vec<String>, Error> {
47 self.command.read_ldopts()
48 }
49
50 pub fn is_defined(&self, name: &str) -> Result<bool, Error> {
51 if let Some(value) = self.dict.get(name) {
52 Ok(value == "define")
53 } else {
54 Err(other_error("No such entry".to_string()))
55 }
56 }
57
58 pub fn emit_cargo_ldopts(&self) {
59 self.command.emit_cargo_ldopts()
60 }
61
62 pub fn perl_api_version(&self) -> i32 {
63 let config = &self.dict["PERL_API_VERSION"];
64 let config = config.trim();
65 i32::from_str_radix(String::from(config).trim(), 10).unwrap()
66 }
67
68 pub fn emit_all_perlapi_versions(&self, min: i32) {
69 let local_time = Local::now();
70 let current_year = local_time.year();
71 println!("# curyear = {}", current_year);
72 let yearly_perl_ver = self.yearly_perl_version(current_year);
73 println!("# yearly perl = {}", yearly_perl_ver);
74 self.emit_perlapi_vers(min, yearly_perl_ver)
75 }
76
77 pub fn yearly_perl_version(&self, year: i32) -> i32 {
78 (year - 2004) * 2
79 }
80
81 pub fn emit_perlapi_vers(&self, min: i32, max: i32) {
82 let ver = self.perl_api_version();
83 for v in min..=max {
84 if v % 2 == 1 {
85 continue;
86 }
87 println!("cargo::rustc-check-cfg=cfg(perlapi_ver{})", v);
89 if ver >= v {
90 println!("cargo:rustc-cfg=perlapi_ver{}", v);
91 }
92 }
93 }
94
95 pub fn emit_features(&self, configs: &[&str]) {
96 for &cfg in configs.iter() {
97 println!("# perl config {} = {:?}", cfg, self.dict.get(&String::from(cfg)));
98 println!("cargo::rustc-check-cfg=cfg(perl_{})", cfg);
100 if self.is_defined(cfg).unwrap() {
101 println!("cargo:rustc-cfg=perl_{}", cfg);
102 }
103 }
104 }
105}
106
107fn read_config(cmd: &PerlCommand, configs: &[&str]) -> Result<ConfigDict, Error> {
108 let config = cmd.read_raw_config(configs)?;
109 let lines = config.lines().map(String::from).collect();
110 Ok(lines_to_hashmap(lines))
111}
112
113fn lines_to_hashmap(lines: Vec<String>) -> ConfigDict {
114 let mut dict = HashMap::new();
115 for line in lines.iter() {
116 let kv: Vec<String> = line.splitn(2, '\t').map(String::from).collect();
117 if kv.len() == 2 {
118 dict.insert(kv[0].clone(), kv[1].clone());
119 }
120 }
121 dict
122}