Copia in raw anche i modelli citati per riferimento esterno
Terzo caso di "[-4] Dati di input non completi" in Creo Distributed Batch, dopo i soppressi e le copie ambigue del commit precedente: falliva 9255728001, e solo lui fra i sei assiemi del batch. Il file in raw/ era identico bit per bit a quello sulla share, quindi non era il modello: mancava il contorno. Il suo sottoassieme _200 e' legato ad altri due (9255708017, 9255708018) da assembly feature e datum copiati, e monta una vite V6-12--_-_U5933_C il cui generico uni5933.prt non era in raw/. Nessuno dei sei file compariva in "members" ne' fra i piazzamenti: i due lettori esistenti non potevano vederli. Quei modelli stanno in una tabella a parte del .asm - array \xf2\xf7\x05 … \xf3 con elementi \xe3\xe2<tipo><nome>\0 - che ora si legge con EstraiCodiciRiferimentiEsterni, riusando la normalizzazione di #AF<n> e istanza<generico> gia' fatta per i membri. A differenza dei soppressi si ricorre dentro: Creo carica il modello citato con tutto il suo albero, e infatti 9255700182 arriva solo per quella via. La tabella contiene anche nomi di feature (MIRROR3, CHAMFER1) che dal record non si distinguono dai modelli. Non e' un problema: come per i soppressi si cerca ogni nome nell'indice e si ignora quello che non c'e'. Per lo stesso motivo questi codici restano fuori dai "non trovati", e la coda di scansione porta ora un flag che tiene fuori anche i rami raggiunti per riferimento esterno - la lista dei componenti mancanti continua a parlare solo della distinta. Documentato in docs/formato-asm-record.md §7.5. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
54f267b508
commit
13f6de6402
5 files changed
+147
-15
No files matched your search
@@ -225,6 +225,45 @@ public static class AsmRecordReader
|
||||
return soppressi;
|
||||
}
|
||||
|
||||
/// <summary>Modelli che l'assieme cita nella tabella dei riferimenti (§7.5): oltre ai propri
|
||||
/// membri comprende quelli legati da **riferimenti esterni** - assembly feature, datum
|
||||
/// copiati - che non compaiono né in "members" né come piazzamento, ma che Creo carica
|
||||
/// comunque per aprire l'assieme.
|
||||
///
|
||||
/// Terza lista dopo <see cref="EstraiCodiciReferenziati"/> ("cosa c'è in distinta") e <see
|
||||
/// cref="EstraiCodiciSoppressi"/>: come quest'ultima risponde a "cosa serve su disco", non a
|
||||
/// "cosa va nella BOM. L'array contiene anche nomi di feature (MIRROR3, CHAMFER1...) e non
|
||||
/// solo di modelli: non si riesce a distinguerli dal record, ma non danno fastidio perché il
|
||||
/// chiamante li cerca nell'indice e ignora quelli che non ci sono.</summary>
|
||||
public static HashSet<string> EstraiCodiciRiferimentiEsterni(string percorsoAsm)
|
||||
{
|
||||
string testo = Encoding.Latin1.GetString(File.ReadAllBytes(percorsoAsm));
|
||||
var codici = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
for (int i = testo.IndexOf(InizioRiferimenti, StringComparison.Ordinal); i >= 0;
|
||||
i = testo.IndexOf(InizioRiferimenti, i + 1, StringComparison.Ordinal))
|
||||
{
|
||||
int max = Math.Min(LunghezzaMassimaRiferimenti, testo.Length - i);
|
||||
int fine = testo.IndexOf(FineRiferimenti, i, max);
|
||||
foreach (Match m in RiferimentoRegex.Matches(testo.Substring(i, fine >= 0 ? fine - i : max)))
|
||||
{
|
||||
var bracket = IstanzaConGenericoRegex.Match(m.Groups[1].Value);
|
||||
codici.Add(bracket.Success
|
||||
? bracket.Groups[2].Value
|
||||
: SuffissoArrayFeatureRegex.Replace(m.Groups[1].Value, ""));
|
||||
}
|
||||
}
|
||||
return codici;
|
||||
}
|
||||
|
||||
// Array dei modelli referenziati: "\xf2\xf7\x05" lo apre, "\xf3" lo chiude, ogni elemento e'
|
||||
// "\xe3\xe2<tipo><nome>\x00" (§7.5). Il tetto di lunghezza limita il danno se il terminatore
|
||||
// non si trova dove atteso: si perde qualche riferimento, non si raccoglie mezzo file.
|
||||
private const string InizioRiferimenti = "ò÷\u0005ãâ";
|
||||
private const char FineRiferimenti = 'ó';
|
||||
private const int LunghezzaMassimaRiferimenti = 4096;
|
||||
private static readonly Regex RiferimentoRegex = new(
|
||||
@"\xe3\xe2[\x01\x02]([\x20-\x7e]{3,})\x00", RegexOptions.Compiled);
|
||||
|
||||
// "Componente ID 52 (9230100043.PRT)" - la stringa cambia con la localizzazione Creo del
|
||||
// file, come in AssemblyComponentScanner.HaPlacement. Minimo 3 caratteri per lo stesso
|
||||
// motivo per cui li' i token generici partono da 3: sotto quella soglia si raccoglie
|
||||
|
||||
+32
-5
@@ -875,14 +875,18 @@ public partial class Form1 : Form
|
||||
{
|
||||
// Ogni assieme viaggia con la cartella della share da cui proviene: e' li' che Creo
|
||||
// cerca per primi i suoi componenti, quindi e' li' che li cerchiamo anche noi.
|
||||
var daScansionare = new Queue<(string File, string? CartellaOrigine)>(
|
||||
asmIniziali.Select(f => (f, (string?)null)));
|
||||
// "Esterno" marca i rami raggiunti da un riferimento esterno invece che dalla distinta:
|
||||
// servono su disco ma non sono componenti, quindi i loro codici mancanti non vanno fra i
|
||||
// "non trovati" (sarebbero falsi allarmi, come per i soppressi).
|
||||
var daScansionare = new Queue<(string File, string? CartellaOrigine, bool Esterno)>(
|
||||
asmIniziali.Select(f => (f, (string?)null, false)));
|
||||
var codiciIniziali = asmIniziali.Select(f => Path.GetFileName(f).Split('.')[0]).ToList();
|
||||
var codiciVisti = new HashSet<string>(
|
||||
codiciIniziali.Concat(codiciIniziali.Select(AssemblyComponentScanner.CodiceRadice)),
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
var codiciSoppressiVisti = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
var codiciEsterniVisti = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
var trovati = new List<(string Codice, string Tipo, string Percorso)>();
|
||||
var codiciNonTrovati = new List<string>();
|
||||
if (daScansionare.Count == 0 || _dbPath is null)
|
||||
@@ -894,7 +898,7 @@ public partial class Form1 : Form
|
||||
int processati = 0;
|
||||
while (daScansionare.Count > 0)
|
||||
{
|
||||
var (asm, cartellaOrigine) = daScansionare.Dequeue();
|
||||
var (asm, cartellaOrigine, esterno) = daScansionare.Dequeue();
|
||||
cartellaOrigine ??= CartellaDiOrigine(asm, candidati);
|
||||
processati++;
|
||||
foreach (var codice in EstraiCodiciReferenziati(asm, codiciNoti.Keys))
|
||||
@@ -904,7 +908,8 @@ public partial class Form1 : Form
|
||||
|
||||
if (!candidati.TryGetValue(codice, out var perCodice))
|
||||
{
|
||||
codiciNonTrovati.Add(codice);
|
||||
if (!esterno)
|
||||
codiciNonTrovati.Add(codice);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -915,7 +920,7 @@ public partial class Form1 : Form
|
||||
if (tipo == "asm")
|
||||
{
|
||||
daScansionare.Enqueue((Path.Combine(_ultimaCartellaRaw!, Path.GetFileName(percorso)),
|
||||
Path.GetDirectoryName(percorso)));
|
||||
Path.GetDirectoryName(percorso), esterno));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -936,6 +941,28 @@ public partial class Form1 : Form
|
||||
trovati.Add((codice, tipo, percorso));
|
||||
}
|
||||
}
|
||||
|
||||
// I riferimenti esterni (assembly feature, datum copiati verso un altro modello) non
|
||||
// sono componenti e non compaiono fra i piazzamenti, ma Creo carica il modello citato
|
||||
// per aprire l'assieme - e con lui i *suoi* componenti, quindi qui, a differenza dei
|
||||
// soppressi, si ricorre dentro. Vedi docs/formato-asm-record.md §7.5.
|
||||
foreach (var codice in AsmRecordReader.EstraiCodiciRiferimentiEsterni(asm))
|
||||
{
|
||||
if (!codiciEsterniVisti.Add(codice) || codiciVisti.Contains(codice))
|
||||
continue;
|
||||
if (!candidati.TryGetValue(codice, out var perCodice))
|
||||
continue;
|
||||
foreach (var (tipo, percorso) in ScegliPerCartella(perCodice, cartellaOrigine))
|
||||
{
|
||||
CopiaFileTrovati(new[] { percorso }, _ultimaCartellaRaw!);
|
||||
trovati.Add((codice, tipo, percorso));
|
||||
if (tipo == "asm")
|
||||
{
|
||||
daScansionare.Enqueue((Path.Combine(_ultimaCartellaRaw!, Path.GetFileName(percorso)),
|
||||
Path.GetDirectoryName(percorso), true));
|
||||
}
|
||||
}
|
||||
}
|
||||
progress?.Report((processati, processati + daScansionare.Count));
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user