Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions manual/src/create_src.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ After stripping the `@@` marker, the remaining text is parsed as a `<definition>
( value [<value>] <string> )+
[ "DEFAULT_VALUE" <string> ]
[ "FORMAT" <length> <digits> ]
| "UNIT" "=" [[ <length> ] <digits> ]
| "UNIT" "=" <string> [[ <length> ] <digits> ]

<description-attr> ::= "DESCRIPTION" "=" <string>

Expand Down Expand Up @@ -392,7 +392,7 @@ After stripping the `@@` marker, the remaining text is parsed as a `<definition>
END

<structure-attribute> ::= <base-offset-attr>
| <dimension-attr>
| <dimension-attr> [ <split> ]
| <size-attr>

<size-attr> ::= "SIZE" "=" <value>
Expand All @@ -402,9 +402,10 @@ After stripping the `@@` marker, the remaining text is parsed as a `<definition>
<instance> ::= "INSTANCE" "=" <identifier> [ <identifier> ]
"STRUCTURE" "=" <identifier>
[ <address-attr> ]
[ <alias-attr> ]
[ <dimension-attr> [ <split> ]]
[ <size-attr> ]
[ <group-attr> ]
( <group-attr> )*
( <overwrite> )*
"END"

Expand All @@ -422,7 +423,7 @@ After stripping the `@@` marker, the remaining text is parsed as a `<definition>
#### Conversion

<conversion> ::= "CONVERSION" "=" <identifier>
"A2L_TYPE" = "=" <conversion-type>
"A2L_TYPE" "=" <conversion-type>
[ "UNIT" "=" <string> <length> <digits> ]
[ "DESCRIPTION" "=" <string> ]
"END"
Expand Down
33 changes: 23 additions & 10 deletions src/creator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,11 @@ struct InstanceDefinition {
a2l_name: Option<String>,
structure_name: String,
address: Option<u32>,
alias: Option<String>,
dimension: Vec<u32>,
split: Option<SplitType>,
_size: Option<u32>, // unused: instance size could be used for address offset calculation
group: Option<GroupAttribute>,
group: Vec<GroupAttribute>,
overwrites: Vec<Overwrite>,
}

Expand Down Expand Up @@ -389,7 +390,7 @@ struct Structure {
struct InstanceElement<'a> {
instance_name: &'a str,
struct_path: &'a [String],
instance_group: &'a Option<GroupAttribute>,
instance_group: &'a [GroupAttribute],
overwrites: &'a Vec<Overwrite>,
}

Expand Down Expand Up @@ -420,6 +421,7 @@ pub(crate) fn create_items_from_sources<'a>(
// This function will handle the creation of items from the source file
// and return the count of inserted items along with any log messages.
let mut creator = Creator::new(a2l_file, target_group, enable_structures, force_old_arrays);
let mut num_files = 0;

for source_file_pattern in source_file_patterns {
// try to expand the pattern using glob, if the input is valid unicode, and if glob understands the pattern
Expand Down Expand Up @@ -462,6 +464,7 @@ pub(crate) fn create_items_from_sources<'a>(
continue;
}
};
num_files += 1; // count how many files were actually processed

creator.messages.push(format!(
"Processing source file '{}'",
Expand All @@ -471,6 +474,10 @@ pub(crate) fn create_items_from_sources<'a>(
}
}

if num_files == 0 {
creator.error("No input pattern matched any source files.".into());
}

if creator.errors > 0 {
Err(creator.messages)
} else {
Expand Down Expand Up @@ -1476,6 +1483,10 @@ impl<'a2l> Creator<'a2l> {
// additionally, INSTANCEs only exist in A2L versions >= 1.7.0, so there is no need to handle old versions here
instance_obj.symbol_link = Some(a2lfile::SymbolLink::new(symbol_name, 0));

if let Some(alias) = &instance.alias {
instance_obj.display_identifier = Some(a2lfile::DisplayIdentifier::new(alias.clone()));
}

if !instance.dimension.is_empty() {
let mut matrix_dim = a2lfile::MatrixDim::new();
for dim in &instance.dimension {
Expand Down Expand Up @@ -2744,15 +2755,17 @@ impl<'a2l> Creator<'a2l> {
};
self.create_group_entry(group_spec, item_name, is_input);
} else if let Some(instance_element) = instance_element
&& let Some(group_attr) = instance_element.instance_group
&& !instance_element.instance_group.is_empty()
{
let group_spec = match group_attr {
GroupAttribute::In(g)
| GroupAttribute::Out(g)
| GroupAttribute::Def(g)
| GroupAttribute::Std(g) => g,
};
self.create_group_entry(group_spec, item_name, is_input);
for group_attr in instance_element.instance_group {
let group_spec = match group_attr {
GroupAttribute::In(g)
| GroupAttribute::Out(g)
| GroupAttribute::Def(g)
| GroupAttribute::Std(g) => g,
};
self.create_group_entry(group_spec, item_name, is_input);
}
} else {
for group_attr in group_attributes {
let group_spec = match group_attr {
Expand Down
24 changes: 19 additions & 5 deletions src/creator/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,20 +467,25 @@ impl<'text> Parser<'_, 'text> {
} else {
None
};
let alias = if self.check_next_token(b"ALIAS") {
let alias = self.parse_tagged_identifier(b"ALIAS", "INSTANCE alias")?;
Some(alias)
} else {
None
};
let (dimension, split) = self.parse_opt_dimension()?;
let size = if self.check_next_token(b"SIZE") {
let size = self.parse_tagged_uint(b"SIZE", "INSTANCE size")?;
Some(size)
} else {
None
};
let group = if self.check_next_token(b"GROUP") {
let mut group = vec![];
while self.check_next_token(b"GROUP") {
self.get_token("")?; // consume GROUP
let group_attribute = self.parse_group_attribute()?;
Some(group_attribute)
} else {
None
};
group.push(group_attribute);
}

let mut overwrites = vec![];
while let Some(overwrite) = self.parse_opt_overwrite()? {
Expand All @@ -494,6 +499,7 @@ impl<'text> Parser<'_, 'text> {
a2l_name,
structure_name,
address,
alias,
dimension,
split,
_size: size,
Expand Down Expand Up @@ -990,6 +996,9 @@ impl<'text> Parser<'_, 'text> {
while let Ok(txt) = self.get_string("") {
split_strings.push(txt);
}
if split_strings.is_empty() {
return Err("SPLIT USE requires at least one string".to_string());
}
Ok(Some(SplitType::Manual(split_strings)))
}
Some(b"USE_TEMPLATE") => {
Expand Down Expand Up @@ -1150,6 +1159,9 @@ impl<'text> Parser<'_, 'text> {
);
}
}
if rows.is_empty() {
return Err("TABLE conversion must have at least one row".to_string());
}

let default_value = if self.check_next_token(b"DEFAULT_VALUE") {
self.get_token("")?; // consume "DEFAULT_VALUE"
Expand Down Expand Up @@ -2169,6 +2181,7 @@ mod tests {
@@ DIMENSION = 3 4 SPLIT
@@ SIZE = 9000
@@ GROUP = GroupName
@@ GROUP IN = FuncName
@@ OVERWRITE x RANGE = [ -1 ... 1 ]
@@ OVERWRITE y CONVERSION = LINEAR 2 3 "s"
@@ END
Expand All @@ -2189,6 +2202,7 @@ mod tests {
assert_eq!(instance_def.address, Some(0x1234));
assert_eq!(instance_def.dimension, vec![3, 4]);
assert_eq!(instance_def._size, Some(9000));
assert_eq!(instance_def.group.len(), 2);
assert_eq!(instance_def.overwrites.len(), 2);
}

Expand Down
Loading