1#[allow(unused)]
2use {
3 anyhow::{Context, Error, Result},
4 jlogger::{jdebug, jerror, jinfo, JloggerBuilder},
5 log::{debug, info, warn},
6 regex::Regex,
7 std::{
8 collections::HashMap,
9 fmt::Display,
10 fs,
11 path::{Path, PathBuf},
12 },
13};
14
15pub enum YoctoVarName {
16 Name(String),
17 NameValAppend(String),
18 NameValRemove(String),
19 NameFlag((String, String)),
20 NameOverride((String, String)),
21 NameOverrideAppend((String, String)),
22 NameOverrideRemove((String, String)),
23 NameAppendOverride((String, String)),
24 NameRemoveOverride((String, String)),
25 InvalidName,
26}
27
28pub enum YoctoVarType {
29 Value,
30 Override(String),
31 Flag(String),
32}
33
34pub struct YoctoVar {
35 name: String,
36 value: String,
37 ovalue: HashMap<String, String>,
38 fvalue: HashMap<String, String>,
39 default: String,
40}
41
42impl YoctoVar {
43 pub fn valid_varable_name(name: &str) -> bool {
44 Regex::new(r"^[A-Z][(A-Z)|(0-9)|_]*$")
45 .unwrap()
46 .is_match(name)
47 }
48
49 pub fn valid_override(s: &str) -> bool {
50 Regex::new(r"^[a-z]([a-z|0-9|-])*$").unwrap().is_match(s)
51 }
52
53 pub fn fix_str(s: &str) -> String {
54 s.trim()
55 .trim_start_matches("\"")
56 .trim_end_matches("\"")
57 .trim()
58 .to_string()
59 }
60
61 pub fn new(statement: Option<&str>) -> Result<Self> {
62 let name = statement
63 .map(|a| YoctoVar::fix_str(a))
64 .unwrap_or_else(|| String::from("UNDEFINE"));
65
66 if !YoctoVar::valid_varable_name(&name) {
67 return Err(Error::msg(format!("Invalid name {}", name)));
68 }
69
70 let n = YoctoVar {
71 name,
72 value: String::new(),
73 default: String::new(),
74 ovalue: HashMap::<String, String>::new(),
75 fvalue: HashMap::<String, String>::new(),
76 };
77
78 Ok(n)
79 }
80
81 pub fn new_default(name: &str, val: &str) -> Result<Self> {
82 let name = YoctoVar::fix_str(name);
83 let err_name = Error::msg(format!("Invalid name {}", name));
84
85 if !YoctoVar::valid_varable_name(&name) {
86 return Err(err_name);
87 }
88
89 Ok(YoctoVar {
90 name,
91 value: String::new(),
92 default: YoctoVar::fix_str(val),
93 ovalue: HashMap::<String, String>::new(),
94 fvalue: HashMap::<String, String>::new(),
95 })
96 }
97
98 pub fn set_default_value(&mut self, val: &str) {
99 self.default = YoctoVar::fix_str(val);
100 }
101
102 pub fn get_default_value(&self) -> &str {
103 self.default.as_str()
104 }
105
106 pub fn update(&mut self, statement: &str, value: &str) -> Result<()> {
107 let statement = YoctoVar::fix_str(statement);
108 let err_statement = Error::msg(format!("Invalid statement {}", statement));
109 let err_name = Error::msg(format!("Invalid name {} != {}", statement, self.name));
110 let val = value;
111
112 let var_remove = |v: &mut String, val: &str| {
114 if v.as_str() == val {
115 v.clear();
116 } else {
117 let val_fix_0 = format!(" {} ", val);
118 let val_fix_1 = format!("{} ", val);
119 let val_fix_2 = format!(" {}", val);
120 let mut nv = v.replace(&val_fix_0, "");
121 nv = nv.replace(&val_fix_1, "");
122 nv = nv.replace(&val_fix_2, "");
123 v.clear();
124 v.push_str(&nv);
125 }
126 };
127
128 match YoctoVar::parse_name(&statement) {
129 YoctoVarName::Name(n) => {
130 if self.name == "UNDEFINE" {
131 self.name.clear();
132 self.name.push_str(&n);
133 } else if n != self.name {
134 return Err(err_name);
135 }
136 self.value.clear();
137 self.value.push_str(val);
138 }
139
140 YoctoVarName::NameValAppend(n) => {
141 if self.name == "UNDEFINE" {
142 self.name.clear();
143 self.name.push_str(&n);
144 } else if n != self.name {
145 return Err(err_name);
146 }
147
148 self.value.push_str(val);
149 }
150
151 YoctoVarName::NameValRemove(n) => {
152 if self.name == "UNDEFINE" {
153 self.name.clear();
154 self.name.push_str(&n);
155 } else if n != self.name {
156 return Err(err_name);
157 }
158
159 var_remove(&mut self.value, val);
160 }
161
162 YoctoVarName::NameFlag((n, f)) => {
163 if self.name == "UNDEFINE" {
164 self.name.clear();
165 self.name.push_str(&n);
166 } else if n != self.name {
167 return Err(err_name);
168 }
169
170 let v = self.fvalue.entry(f).or_insert(String::new());
171 v.clear();
172 v.push_str(val);
173 }
174
175 YoctoVarName::NameOverride((n, o)) => {
176 if self.name == "UNDEFINE" {
177 self.name.clear();
178 self.name.push_str(&n);
179 } else if n != self.name {
180 return Err(err_name);
181 }
182
183 let v = self.ovalue.entry(o).or_insert(String::new());
184 v.clear();
185 v.push_str(val);
186 }
187
188 YoctoVarName::NameOverrideAppend((n, o)) => {
189 if self.name == "UNDEFINE" {
190 self.name.clear();
191 self.name.push_str(&n);
192 } else if n != self.name {
193 return Err(err_name);
194 }
195
196 let v = self.ovalue.entry(o).or_insert(String::new());
197 v.push_str(val);
198 }
199
200 YoctoVarName::NameOverrideRemove((n, o)) => {
201 if self.name == "UNDEFINE" {
202 self.name.clear();
203 self.name.push_str(&n);
204 } else if n != self.name {
205 return Err(err_name);
206 }
207
208 let v = self.ovalue.entry(o).or_insert(String::new());
209 var_remove(v, val);
210 }
211
212 YoctoVarName::NameAppendOverride((n, o)) => {
213 if self.name == "UNDEFINE" {
214 self.name.clear();
215 self.name.push_str(&n);
216 } else if n != self.name {
217 return Err(err_name);
218 }
219
220 let mut nvalue = self.value.clone();
221 nvalue.push_str(val);
222 let v = self.ovalue.entry(o).or_insert(String::new());
223 v.clear();
224 v.push_str(&nvalue);
225 }
226
227 YoctoVarName::NameRemoveOverride((n, o)) => {
228 if self.name == "UNDEFINE" {
229 self.name.clear();
230 self.name.push_str(&n);
231 } else if n != self.name {
232 return Err(err_name);
233 }
234
235 let mut nvalue = self.value.clone();
236 var_remove(&mut nvalue, val);
237 let v = self.ovalue.entry(o).or_insert(String::new());
238 v.clear();
239 v.push_str(&nvalue);
240 }
241
242 _ => return Err(err_statement),
243 }
244
245 Ok(())
246 }
247
248 pub fn key_name<'a>(name: &'a str) -> Result<String> {
249 match YoctoVar::parse_name(name) {
250 YoctoVarName::Name(n) => Ok(n.to_string()),
251 YoctoVarName::NameValAppend(n) => Ok(n.to_string()),
252 YoctoVarName::NameValRemove(n) => Ok(n.to_string()),
253 YoctoVarName::NameFlag((n, _)) => Ok(n.to_string()),
254 YoctoVarName::NameOverride((n, _)) => Ok(n.to_string()),
255 YoctoVarName::NameOverrideAppend((n, _)) => Ok(n.to_string()),
256 YoctoVarName::NameOverrideRemove((n, _)) => Ok(n.to_string()),
257 YoctoVarName::NameAppendOverride((n, _)) => Ok(n.to_string()),
258 YoctoVarName::NameRemoveOverride((n, _)) => Ok(n.to_string()),
259 YoctoVarName::InvalidName => Err(Error::msg(format!("Invalid name {}", name))),
260 }
261 }
262
263 pub fn parse_name<'a>(name: &'a str) -> YoctoVarName {
264 let name = YoctoVar::fix_str(name);
265 let re =
266 Regex::new(r"([A-Z|_]([A-Z|_|0-9]*[A-Z|0-9])*)\[([a-z]([a-z|0-9|_]*[a-z|0-9])*)\]")
267 .unwrap();
268 if let Some(caps) = re.captures(&name) {
269 let n = caps.get(1).unwrap().as_str();
270 let f = caps.get(3).unwrap().as_str();
271 return YoctoVarName::NameFlag((String::from(n), String::from(f)));
272 }
273
274 let re = Regex::new(
275 r"^([A-Z|_]([A-Z|_|0-9]*[A-Z|0-9])*)([:|_][a-z][1-9|a-z|-]*)([:|_][a-z][1-9|a-z|-]*)$",
276 )
277 .unwrap();
278 if let Some(caps) = re.captures(&name) {
279 let n = caps.get(1).unwrap().as_str();
280 let s1 = caps.get(3).unwrap().as_str().trim_start_matches("_");
281 let s2 = caps.get(4).unwrap().as_str().trim_start_matches("_");
282
283 match s1 {
284 "append" => match s2 {
285 "append" => return YoctoVarName::InvalidName,
286 "remove" => return YoctoVarName::InvalidName,
287 _ => {
288 return YoctoVarName::NameAppendOverride((
289 String::from(n),
290 String::from(s2),
291 ))
292 }
293 },
294 "remove" => match s2 {
295 "append" => return YoctoVarName::InvalidName,
296 "remove" => return YoctoVarName::InvalidName,
297 _ => {
298 return YoctoVarName::NameRemoveOverride((
299 String::from(n),
300 String::from(s2),
301 ))
302 }
303 },
304 _ => match s2 {
305 "append" => {
306 return YoctoVarName::NameOverrideAppend((
307 String::from(n),
308 String::from(s1),
309 ))
310 }
311 "remove" => {
312 return YoctoVarName::NameOverrideRemove((
313 String::from(n),
314 String::from(s1),
315 ))
316 }
317 _ => return YoctoVarName::InvalidName,
318 },
319 }
320 }
321
322 let re =
323 Regex::new(r"^([A-Z|_]([A-Z|_|0-9]*[A-Z|0-9])*)([:|_][a-z][1-9|a-z|-]*)$").unwrap();
324 if let Some(caps) = re.captures(&name) {
325 let n = caps.get(1).unwrap().as_str();
326 let s1 = caps.get(3).unwrap().as_str().trim_start_matches("_");
327 match s1 {
328 "append" => return YoctoVarName::NameValAppend(String::from(n)),
329 "remove" => return YoctoVarName::NameValRemove(String::from(n)),
330 _ => return YoctoVarName::NameOverride((String::from(n), String::from(s1))),
331 }
332 }
333
334 let re = Regex::new(r"^([A-Z|_]([A-Z|_|0-9]*[A-Z|0-9])*)$").unwrap();
335 if let Some(caps) = re.captures(&name) {
336 let n = caps.get(1).unwrap().as_str();
337 return YoctoVarName::Name(String::from(n));
338 }
339
340 YoctoVarName::InvalidName
341 }
342
343 pub fn get_value(&self, vtype: YoctoVarType) -> Option<&str> {
344 match vtype {
345 YoctoVarType::Value => Some(&self.value),
346 YoctoVarType::Override(o) => {
347 if let Some(v) = self.ovalue.get(&o) {
348 Some(v)
349 } else {
350 None
351 }
352 }
353 YoctoVarType::Flag(f) => {
354 if let Some(v) = self.fvalue.get(&f) {
355 Some(v)
356 } else {
357 None
358 }
359 }
360 }
361 }
362
363 pub fn get_overrides(&self) -> Vec<&str> {
364 let mut v = Vec::new();
365 for k in self.ovalue.keys() {
366 v.push(k.as_str());
367 }
368 v
369 }
370
371 pub fn get_flags(&self) -> Vec<&str> {
372 let mut v = Vec::new();
373 for k in self.fvalue.keys() {
374 v.push(k.as_str());
375 }
376 v
377 }
378
379 pub fn set_value(&mut self, vtype: YoctoVarType, value: &str) {
380 match vtype {
381 YoctoVarType::Value => {
382 self.value.clear();
383 self.value.push_str(&YoctoVar::fix_str(value));
384 }
385 YoctoVarType::Override(o) => {
386 let v = self.ovalue.entry(o).or_insert(String::new());
387 v.clear();
388 v.push_str(YoctoVar::fix_str(value).as_str());
389 }
390 YoctoVarType::Flag(f) => {
391 let v = self.fvalue.entry(f).or_insert(String::new());
392 v.clear();
393 v.push_str(YoctoVar::fix_str(value).as_str());
394 }
395 }
396 }
397
398 pub fn append(&mut self, vtype: YoctoVarType, value: &str) {
399 match vtype {
400 YoctoVarType::Value => {
401 self.value.push_str(&YoctoVar::fix_str(value));
402 }
403 YoctoVarType::Override(o) => {
404 let v = self.ovalue.entry(o).or_insert(String::new());
405 v.push_str(YoctoVar::fix_str(value).as_str());
406 }
407 YoctoVarType::Flag(f) => {
408 let v = self.fvalue.entry(f).or_insert(String::new());
409 v.push_str(YoctoVar::fix_str(value).as_str());
410 }
411 }
412 }
413
414 pub fn prepend(&mut self, vtype: YoctoVarType, value: &str) {
415 let mut nv = YoctoVar::fix_str(value);
416 match vtype {
417 YoctoVarType::Value => {
418 nv.push_str(&self.value);
419 self.value.clear();
420 self.value.push_str(&nv);
421 }
422
423 YoctoVarType::Override(o) => {
424 let v = self.ovalue.entry(o).or_insert(String::new());
425 nv.push_str(&v);
426 v.clear();
427 v.push_str(&nv);
428 }
429
430 YoctoVarType::Flag(f) => {
431 let v = self.fvalue.entry(f).or_insert(String::new());
432 nv.push_str(&v);
433 v.clear();
434 v.push_str(&nv);
435 }
436 }
437 }
438
439 pub fn add_after(&mut self, vtype: YoctoVarType, value: &str) {
440 match vtype {
441 YoctoVarType::Value => {
442 if !self.value.is_empty() {
443 self.value.push(' ');
444 }
445 self.value.push_str(&YoctoVar::fix_str(value));
446 }
447 YoctoVarType::Override(o) => {
448 let v = self.ovalue.entry(o).or_insert(String::new());
449 if !v.is_empty() {
450 v.push(' ');
451 }
452 v.push_str(YoctoVar::fix_str(value).as_str());
453 }
454 YoctoVarType::Flag(f) => {
455 let v = self.fvalue.entry(f).or_insert(String::new());
456 if !v.is_empty() {
457 v.push(' ');
458 }
459 v.push_str(YoctoVar::fix_str(value).as_str());
460 }
461 }
462 }
463
464 pub fn add_before(&mut self, vtype: YoctoVarType, value: &str) {
465 let mut nv = YoctoVar::fix_str(value);
466 match vtype {
467 YoctoVarType::Value => {
468 if !self.value.is_empty() {
469 nv.push(' ');
470 nv.push_str(&self.value);
471 }
472 self.value.clear();
473 self.value.push_str(&nv);
474 }
475
476 YoctoVarType::Override(o) => {
477 let v = self.ovalue.entry(o).or_insert(String::new());
478 if !v.is_empty() {
479 nv.push(' ');
480 nv.push_str(&v);
481 }
482 v.clear();
483 v.push_str(&nv);
484 }
485
486 YoctoVarType::Flag(f) => {
487 let v = self.fvalue.entry(f).or_insert(String::new());
488 if !v.is_empty() {
489 nv.push(' ');
490 nv.push_str(&v);
491 }
492 v.clear();
493 v.push_str(&nv);
494 }
495 }
496 }
497
498 pub fn variables(value_str: &str) -> Vec<String> {
499 let mut result = Vec::new();
500 let mut s = value_str;
501
502 while let Some(a) = s.find("${") {
503 let start = a + 2;
504 if let Some(end) = s[start..].find("}") {
505 let v = &s[start..start + end];
506 if result.iter().find(|x| *x == v).is_none() {
507 result.push(v.to_string());
508 }
509
510 s = &s[start + end + 1..];
511 } else {
512 break;
513 }
514 }
515
516 result
517 }
518
519 pub fn value(&self, overrides: Option<&str>) -> &str {
520 if let Some(s) = overrides {
521 let mut olist: Vec<&str> = s.split(":").collect();
522 if !olist.is_empty() {
523 olist.reverse();
524 for o in olist {
525 if let Some(va) = self.ovalue.get(o) {
526 return va.as_str();
527 }
528 }
529 }
530 }
531 if self.value.is_empty() {
532 self.default.as_str()
533 } else {
534 self.value.as_str()
535 }
536 }
537
538 pub fn name(&self) -> &str {
539 self.name.as_str()
540 }
541}
542
543impl Display for YoctoVar {
544 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
545 let mut output = String::new();
546 output.push_str(
547 format!(
548 "{} = {}\n",
549 self.name(),
550 self.get_value(YoctoVarType::Value).unwrap_or("")
551 )
552 .as_str(),
553 );
554
555 for o in self.get_overrides() {
556 output.push_str(
557 format!(
558 "{}_{} = {}\n",
559 self.name(),
560 o,
561 self.get_value(YoctoVarType::Override(o.to_string()))
562 .unwrap()
563 )
564 .as_str(),
565 );
566 }
567
568 for f in self.get_flags() {
569 output.push_str(
570 format!(
571 "{}[{}] = {}\n",
572 self.name(),
573 f,
574 self.get_value(YoctoVarType::Flag(f.to_string())).unwrap()
575 )
576 .as_str(),
577 );
578 }
579 write!(f, "{}", output)
580 }
581}
582
583pub struct DataStore {
584 store: HashMap<String, YoctoVar>,
585}
586
587impl DataStore {
588 pub fn new() -> Self {
589 DataStore {
590 store: HashMap::<String, YoctoVar>::new(),
591 }
592 }
593
594 pub fn expand_value(&self, value: &str, gstore: Option<&DataStore>) -> Result<String> {
595 let mut expand_str = YoctoVar::fix_str(value);
596 let variables = YoctoVar::variables(value);
597 let mut overrides = String::new();
598
599 if let Some(d) = gstore {
600 if let Some(o) = d.value("OVERRIDES") {
601 if let Some(ostr) = o.get_value(YoctoVarType::Value) {
602 overrides.push_str(ostr);
603 }
604 }
605 }
606
607 if let Some(o) = self.store.get("OVERRIDES") {
608 if let Some(ostr) = o.get_value(YoctoVarType::Value) {
609 overrides.push_str(ostr);
610 }
611 }
612
613 for v in variables {
614 if v.starts_with("@") {
615 let mut processed = false;
616 if v.starts_with("@os.path.abspath(") {
617 if let Some(start) = v.find("(") {
618 if let Some(end) = v.find(")") {
619 let u = &v[start + 1..end]
620 .trim()
621 .trim_start_matches("\"")
622 .trim_end_matches("\"")
623 .trim_start_matches("\'")
624 .trim_end_matches("\'");
625
626 if let Ok(p) = fs::canonicalize(u) {
627 if p.is_dir() {
628 let orig = format!("${{{}}}", v);
629 expand_str =
630 expand_str.replace(orig.as_str(), p.to_str().unwrap());
631 processed = true;
632 }
633 }
634 }
635 }
636 }
637 if !processed {
638 warn!("Unknown python founction {}", v);
639 let orig = format!("${{{}}}", v);
640 expand_str = expand_str.replace(orig.as_str(), "__UNKNOWN__");
641 }
642 continue;
643 }
644
645 let mut var = None;
646
647 if let Some(yv) = self.store.get(v.as_str()) {
648 var = Some(yv);
649 } else {
650 if let Some(d) = gstore {
651 if let Some(yv) = d.value(v.as_str()) {
652 var = Some(&yv);
653 }
654 }
655 }
656
657 let var = var.ok_or(Error::msg(format!("Unknown variable {}.", v)))?;
658
659 let estr = self.expand_value(var.value(Some(&overrides)), gstore)?;
660 let orig = format!("${{{}}}", v);
661 expand_str = expand_str.replace(orig.as_str(), estr.as_str());
662 }
663
664 if expand_str.is_empty() {
665 Ok(value.to_string())
666 } else {
667 Ok(expand_str)
668 }
669 }
670
671 pub fn from_conf_str(&mut self, conf_str: &str, gstore: Option<&DataStore>) -> Result<()> {
672 let conf_str = conf_str
673 .lines()
674 .filter(|l| !l.starts_with("#"))
675 .map(|a| a.trim().to_string())
676 .collect::<Vec<String>>()
677 .join("\n")
678 .replace("\\\n", "");
679
680 let err_statement = Error::msg(format!("Invalid statement"));
681 for l in conf_str.lines() {
682 let v = l.split("??=").collect::<Vec<&str>>();
683 if v.len() == 2 {
684 let val = YoctoVar::fix_str(v[1]);
685 match YoctoVar::parse_name(v[0]) {
686 YoctoVarName::Name(n) => {
687 let mut found = false;
688 let yv = YoctoVar::new_default(&n, &val)?;
689 if let Some(d) = gstore {
690 if d.value(&n).is_some() {
691 found = true;
692 }
693 }
694
695 if !found {
696 if self.store.get(&n).is_none() {
697 self.store.insert(n, yv);
698 }
699 }
700 }
701 _ => return Err(err_statement),
702 }
703 continue;
704 }
705
706 let v = l.split("?=").collect::<Vec<&str>>();
707 if v.len() == 2 {
708 let val = YoctoVar::fix_str(v[1]);
709 let mut found = false;
710 match YoctoVar::parse_name(v[0].trim()) {
711 YoctoVarName::Name(n) => {
712 let mut yv = YoctoVar::new(Some(&n))?;
713 yv.set_value(YoctoVarType::Value, &val);
714
715 if let Some(d) = gstore {
716 if d.value(&n).is_some() {
717 found = true;
718 }
719 }
720
721 if !found {
722 if self.store.get(&n).is_none() {
723 self.store.insert(n, yv);
724 }
725 }
726 }
727 YoctoVarName::NameOverride((n, o)) => {
728 if let Some(d) = gstore {
729 if let Some(yv) = d.value(&n) {
730 if yv.get_value(YoctoVarType::Override(o.clone())).is_some() {
731 found = true;
732 }
733 }
734 }
735
736 if !found {
737 if let Some(yv) = self.store.get_mut(&n) {
738 if yv.get_value(YoctoVarType::Override(o.clone())).is_none() {
739 yv.set_value(YoctoVarType::Override(o.clone()), &val);
740 }
741 } else {
742 let mut yv = YoctoVar::new(Some(&n))?;
743 yv.set_value(YoctoVarType::Override(o.clone()), &val);
744 self.store.insert(n, yv);
745 }
746 }
747 }
748 YoctoVarName::NameFlag((n, f)) => {
749 if let Some(d) = gstore {
750 if let Some(yv) = d.value(&n) {
751 if yv.get_value(YoctoVarType::Flag(f.clone())).is_some() {
752 found = true;
753 }
754 }
755 }
756
757 if !found {
758 if let Some(yv) = self.store.get_mut(&n) {
759 if yv.get_value(YoctoVarType::Flag(f.clone())).is_none() {
760 yv.set_value(YoctoVarType::Flag(f.clone()), &val);
761 }
762 } else {
763 let mut yv = YoctoVar::new(Some(&n))?;
764 yv.set_value(YoctoVarType::Flag(f.clone()), &val);
765 self.store.insert(n, yv);
766 }
767 }
768 }
769 _ => return Err(err_statement),
770 }
771
772 continue;
773 }
774
775 let v = l.split(":=").collect::<Vec<&str>>();
776 if v.len() == 2 {
777 let val = YoctoVar::fix_str(v[1]);
778 match YoctoVar::parse_name(v[0].trim()) {
779 YoctoVarName::Name(n) => {
780 let ev = self.expand_value(&val, gstore)?;
781 if let Some(yv) = self.store.get_mut(&n) {
782 yv.set_value(YoctoVarType::Value, ev.as_str());
783 } else {
784 let mut yv = YoctoVar::new(Some(&n))?;
785 yv.set_value(YoctoVarType::Value, ev.as_str());
786 self.store.insert(n, yv);
787 }
788 }
789
790 YoctoVarName::NameOverride((n, o)) => {
791 let ev = self.expand_value(&val, gstore)?;
792 if let Some(yv) = self.store.get_mut(&n) {
793 yv.set_value(YoctoVarType::Override(o.clone()), ev.as_str());
794 } else {
795 let ev = self.expand_value(&val, gstore)?;
796 let mut yv = YoctoVar::new(Some(&n))?;
797 yv.set_value(YoctoVarType::Override(o.clone()), ev.as_str());
798 self.store.insert(n, yv);
799 }
800 }
801
802 YoctoVarName::NameFlag((n, f)) => {
803 let ev = self.expand_value(&val, gstore)?;
804 if let Some(yv) = self.store.get_mut(&n) {
805 yv.set_value(YoctoVarType::Flag(f.clone()), ev.as_str());
806 } else {
807 let ev = self.expand_value(&val, gstore)?;
808 let mut yv = YoctoVar::new(Some(&n))?;
809 yv.set_value(YoctoVarType::Flag(f.clone()), ev.as_str());
810 self.store.insert(n, yv);
811 }
812 }
813
814 _ => return Err(err_statement),
815 }
816 continue;
817 }
818
819 let v = l.split("+=").collect::<Vec<&str>>();
820 if v.len() == 2 {
821 let val = YoctoVar::fix_str(v[1]);
822 match YoctoVar::parse_name(v[0].trim()) {
823 YoctoVarName::Name(n) => {
824 if let Some(yv) = self.store.get_mut(&n) {
825 yv.add_after(YoctoVarType::Value, &val);
826 } else {
827 let mut yv = YoctoVar::new(Some(&n))?;
828 yv.add_after(YoctoVarType::Value, &val);
829 self.store.insert(n, yv);
830 }
831 }
832 YoctoVarName::NameOverride((n, o)) => {
833 if let Some(yv) = self.store.get_mut(&n) {
834 yv.add_after(YoctoVarType::Override(o.clone()), &val);
835 } else {
836 let mut yv = YoctoVar::new(Some(&n))?;
837 yv.add_after(YoctoVarType::Override(o.clone()), &val);
838 self.store.insert(n, yv);
839 }
840 }
841 YoctoVarName::NameFlag((n, f)) => {
842 if let Some(yv) = self.store.get_mut(&n) {
843 yv.add_after(YoctoVarType::Flag(f.clone()), &val);
844 } else {
845 let mut yv = YoctoVar::new(Some(&n))?;
846 yv.add_after(YoctoVarType::Flag(f.clone()), &val);
847 self.store.insert(n, yv);
848 }
849 }
850 _ => return Err(err_statement),
851 }
852
853 continue;
854 }
855
856 let v = l.split("=+").collect::<Vec<&str>>();
857 if v.len() == 2 {
858 let val = YoctoVar::fix_str(v[1]);
859 match YoctoVar::parse_name(v[0].trim()) {
860 YoctoVarName::Name(n) => {
861 if let Some(yv) = self.store.get_mut(&n) {
862 yv.add_before(YoctoVarType::Value, &val);
863 } else {
864 let mut yv = YoctoVar::new(Some(&n))?;
865 yv.add_before(YoctoVarType::Value, &val);
866 self.store.insert(n, yv);
867 }
868 }
869 YoctoVarName::NameOverride((n, o)) => {
870 if let Some(yv) = self.store.get_mut(&n) {
871 yv.add_before(YoctoVarType::Override(o.clone()), &val);
872 } else {
873 let mut yv = YoctoVar::new(Some(&n))?;
874 yv.add_before(YoctoVarType::Override(o.clone()), &val);
875 self.store.insert(n, yv);
876 }
877 }
878 YoctoVarName::NameFlag((n, f)) => {
879 if let Some(yv) = self.store.get_mut(&n) {
880 yv.add_before(YoctoVarType::Flag(f.clone()), &val);
881 } else {
882 let mut yv = YoctoVar::new(Some(&n))?;
883 yv.add_before(YoctoVarType::Flag(f.clone()), &val);
884 self.store.insert(n, yv);
885 }
886 }
887 _ => return Err(err_statement),
888 }
889 continue;
890 }
891
892 let v = l.split(".=").collect::<Vec<&str>>();
893 if v.len() == 2 {
894 let val = YoctoVar::fix_str(v[1]);
895 match YoctoVar::parse_name(v[0]) {
896 YoctoVarName::Name(n) => {
897 if let Some(yv) = self.store.get_mut(&n) {
898 yv.append(YoctoVarType::Value, &val);
899 } else {
900 let mut yv = YoctoVar::new(Some(&n))?;
901 yv.append(YoctoVarType::Value, &val);
902 self.store.insert(n, yv);
903 }
904 }
905 YoctoVarName::NameOverride((n, o)) => {
906 if let Some(yv) = self.store.get_mut(&n) {
907 yv.append(YoctoVarType::Override(o.clone()), &val);
908 } else {
909 let mut yv = YoctoVar::new(Some(&n))?;
910 yv.append(YoctoVarType::Override(o.clone()), &val);
911 self.store.insert(n, yv);
912 }
913 }
914 YoctoVarName::NameFlag((n, f)) => {
915 if let Some(yv) = self.store.get_mut(&n) {
916 yv.append(YoctoVarType::Flag(f.clone()), &val);
917 } else {
918 let mut yv = YoctoVar::new(Some(&n))?;
919 yv.append(YoctoVarType::Flag(f.clone()), &val);
920 self.store.insert(n, yv);
921 }
922 }
923 _ => return Err(err_statement),
924 }
925 continue;
926 }
927
928 let v = l.split("=.").collect::<Vec<&str>>();
929 if v.len() == 2 {
930 let val = YoctoVar::fix_str(v[1]);
931 match YoctoVar::parse_name(v[0]) {
932 YoctoVarName::Name(n) => {
933 if let Some(yv) = self.store.get_mut(&n) {
934 yv.prepend(YoctoVarType::Value, &val);
935 } else {
936 let mut yv = YoctoVar::new(Some(&n))?;
937 yv.prepend(YoctoVarType::Value, &val);
938 self.store.insert(n, yv);
939 }
940 }
941 YoctoVarName::NameOverride((n, o)) => {
942 if let Some(yv) = self.store.get_mut(&n) {
943 yv.prepend(YoctoVarType::Override(o.clone()), &val);
944 } else {
945 let mut yv = YoctoVar::new(Some(&n))?;
946 yv.prepend(YoctoVarType::Override(o.clone()), &val);
947 self.store.insert(n, yv);
948 }
949 }
950 YoctoVarName::NameFlag((n, f)) => {
951 if let Some(yv) = self.store.get_mut(&n) {
952 yv.prepend(YoctoVarType::Flag(f.clone()), &val);
953 } else {
954 let mut yv = YoctoVar::new(Some(&n))?;
955 yv.prepend(YoctoVarType::Flag(f.clone()), &val);
956 self.store.insert(n, yv);
957 }
958 }
959 _ => return Err(err_statement),
960 }
961 continue;
962 }
963
964 let v = l.split("=").collect::<Vec<&str>>();
966 if v.len() == 2 {
967 let key_name = YoctoVar::key_name(v[0])?;
968 if let Some(yv) = self.store.get_mut(&key_name) {
969 yv.update(v[0], YoctoVar::fix_str(v[1]).as_str())?;
970 } else {
971 let mut yv = YoctoVar::new(Some(&key_name))?;
972 yv.update(v[0], YoctoVar::fix_str(v[1]).as_str())?;
973 self.store.insert(key_name, yv);
974 }
975 }
976 }
977
978 Ok(())
979 }
980
981 pub fn from_conf_file(&mut self, file: &str, gstore: Option<&DataStore>) -> Result<()> {
982 self.from_conf_str(
983 fs::read_to_string(file)
984 .with_context(|| format!("Failed to read {}", file))?
985 .as_str(),
986 gstore,
987 )
988 }
989
990 pub fn value(&self, key: &str) -> Option<&YoctoVar> {
991 self.store.get(key)
992 }
993
994 pub fn data_store(&self) -> &HashMap<String, YoctoVar> {
995 &self.store
996 }
997
998 pub fn add(&mut self, yv: YoctoVar) {
999 let key = yv.name();
1000 self.store.insert(key.to_string(), yv);
1001 }
1002}
1003
1004impl Display for DataStore {
1005 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1006 let mut output = String::new();
1007 for (_k, yv) in self.store.iter() {
1008 output.push_str(&format!(" {}", yv));
1009 }
1010
1011 write!(f, "{}", output)
1012 }
1013}
1014
1015#[cfg(test)]
1016mod yocto_test;