fix(abcip): accept module-defined I/O tag paths (Local:1:I.Data, ABB_OmniCore:I.X)
Live read-only check: a production CompactLogix lists the module tag ABB_OmniCore:I in @tags and libplctag reads ABB_OmniCore:I.ConnectionFaulted without complaint, but the driver refused the path as malformed (identifier rule had no colon) and reported the tag BadCommunicationError. Colon-separated identifier/slot parts are now legal in the controller-scope base segment only (never past it, never under Program: scope).
This commit is contained in:
@@ -100,7 +100,10 @@ public sealed record AbCipTagPath(
|
||||
var bracketIdx = part.IndexOf('[');
|
||||
if (bracketIdx < 0)
|
||||
{
|
||||
if (!IsValidIdent(part)) return null;
|
||||
// The controller-scope base name of a module-defined I/O tag carries colons
|
||||
// (Local:1:I, ABB_OmniCore:I) — legal in the first segment only.
|
||||
var isModuleBase = segments.Count == 0 && programScope is null && IsValidModuleBase(part);
|
||||
if (!isModuleBase && !IsValidIdent(part)) return null;
|
||||
segments.Add(new AbCipTagPathSegment(part, []));
|
||||
continue;
|
||||
}
|
||||
@@ -122,6 +125,25 @@ public sealed record AbCipTagPath(
|
||||
return new AbCipTagPath(programScope, segments, bitIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <c>true</c> for a module-defined I/O tag base name: an identifier followed by one or more
|
||||
/// <c>:</c>-separated identifier or slot-number parts (<c>Local:1:I</c>, <c>ABB_OmniCore:I</c>).
|
||||
/// </summary>
|
||||
/// <param name="s">The candidate base name.</param>
|
||||
/// <returns><c>true</c> when <paramref name="s"/> is a module tag base name.</returns>
|
||||
private static bool IsValidModuleBase(string s)
|
||||
{
|
||||
var parts = s.Split(':');
|
||||
if (parts.Length < 2 || !IsValidIdent(parts[0])) return false;
|
||||
for (var i = 1; i < parts.Length; i++)
|
||||
{
|
||||
var p = parts[i];
|
||||
if (p.Length == 0) return false;
|
||||
if (!IsValidIdent(p) && !p.All(char.IsAsciiDigit)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool IsValidIdent(string s)
|
||||
{
|
||||
if (string.IsNullOrEmpty(s)) return false;
|
||||
|
||||
Reference in New Issue
Block a user