Skip to content

Commit 50eed3b

Browse files
authored
Merge pull request #2 from kuro68k/Path-fix
Path fix
2 parents 79c7bdc + bcc6e8e commit 50eed3b

File tree

5 files changed

+111
-55
lines changed

5 files changed

+111
-55
lines changed

custom_fields.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ bom_footprint substitute footprint name
44
precision e.g. 1%, X5R
55
bom_note text of note
66
bom_partno manufacturer's part number
7+
bom_no_part excludes part from BOM if set to "true"

kibom/Component.cs

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class Component
3838
public string part_no = "";
3939
public string note = "";
4040
public string code;
41+
public bool no_part = false;
4142

4243
static List<DefaultComp> default_list = new List<DefaultComp>();
4344

@@ -143,6 +144,52 @@ public static double ValueToNumeric(string value)
143144
return nv;
144145
}
145146

147+
#region Group Building
148+
149+
public static List<DesignatorGroup> BuildDesignatorGroups(List<Component> comp_list)
150+
{
151+
var groups = new List<DesignatorGroup>();
152+
153+
foreach (Component comp in comp_list)
154+
{
155+
bool found = false;
156+
for (int i = 0; i < groups.Count; i++)
157+
{
158+
if (groups[i].designator == comp.designator)
159+
{
160+
groups[i].comp_list.Add(comp);
161+
found = true;
162+
break;
163+
}
164+
}
165+
if (!found)
166+
{
167+
var new_group = new DesignatorGroup();
168+
new_group.designator = comp.designator;
169+
new_group.comp_list = new List<Component>();
170+
new_group.comp_list.Add(comp);
171+
groups.Add(new_group);
172+
}
173+
}
174+
175+
return groups;
176+
}
177+
178+
public static void SortDesignatorGroups(ref List<DesignatorGroup> groups)
179+
{
180+
foreach (DesignatorGroup g in groups)
181+
{
182+
// sort by value
183+
g.comp_list.Sort((a, b) => a.numeric_value.CompareTo(b.numeric_value));
184+
}
185+
}
186+
187+
#endregion
188+
189+
#region Merging
190+
191+
// Designator groups contain multiple components with the same designators.
192+
// Sort the components into batches of identical ones.
146193
public static List<DesignatorGroup> MergeComponents(List<DesignatorGroup> groups)
147194
{
148195
var new_groups = new List<DesignatorGroup>();
@@ -164,28 +211,31 @@ public static List<DesignatorGroup> MergeComponents(List<DesignatorGroup> groups
164211
}
165212
else
166213
{
167-
if ((last_c.value != c.value) || // new value group
214+
if ((last_c.value != c.value) ||
168215
(last_c.footprint != c.footprint) ||
169216
(last_c.code != c.code) ||
170217
(last_c.note != c.note) ||
171218
(last_c.part_no != c.part_no) ||
172219
(last_c.precision != c.precision))
173220
{
221+
// different, create new value group
174222
last_c.reference = SortCommaSeparatedString(last_c.reference);
175223
new_g.comp_list.Add(last_c);
176224
last_c = c;
177225
last_c.count = 1;
178226
}
179-
else // same, add to value group
227+
else // same, add to value group
180228
{
181229
last_c.reference += ", " + c.reference;
182230
last_c.count++;
183231
}
184232
}
185233
}
186234

235+
// above loop doesn't add the last group to the list
187236
last_c.reference = SortCommaSeparatedString(last_c.reference);
188237
new_g.comp_list.Add(last_c);
238+
// start a new designator group
189239
new_groups.Add(new_g);
190240
}
191241

@@ -228,10 +278,32 @@ static string SortCommaSeparatedString(string s)
228278
string returnValue = "";
229279
for (int i = stringArray.GetLowerBound(0); i <= stringArray.GetUpperBound(0); i++)
230280
{
231-
returnValue = returnValue + stringArray[i] + ",";
281+
returnValue = returnValue + stringArray[i].Trim() + ", ";
282+
}
283+
return returnValue.Remove(returnValue.Length - 2, 1);
284+
}
285+
286+
public static void SortComponents(ref List<DesignatorGroup> groups)
287+
{
288+
foreach (DesignatorGroup g in groups)
289+
{
290+
g.comp_list.Sort((a, b) => CompareDesignators(a.reference, b.reference));
232291
}
233-
return returnValue.Remove(returnValue.Length - 1, 1);
234292
}
235293

294+
static int CompareDesignators(string a, string b)
295+
{
296+
if (a.Contains(','))
297+
a = a.Substring(0, a.IndexOf(','));
298+
if (b.Contains(','))
299+
b = b.Substring(0, b.IndexOf(','));
300+
int ai, bi;
301+
int.TryParse(a.Substring(1), out ai);
302+
int.TryParse(b.Substring(1), out bi);
303+
return ai.CompareTo(bi);
304+
}
305+
306+
#endregion
307+
236308
}
237309
}

kibom/Output.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,15 @@ public static void OutputTSV(List<DesignatorGroup> groups, HeaderBlock header, s
2626
if (header.company != "")
2727
sw.WriteLine("Company\t" + header.company);
2828
sw.WriteLine("");
29+
//sw.WriteLine("Type\tDesignation\tValue\tPart Name");
2930

3031
foreach (DesignatorGroup g in groups)
3132
{
3233
// check for groups that are entire "no part"
3334
bool all_no_part = true;
3435
foreach (Component c in g.comp_list)
3536
{
36-
if (c.footprint_normalized != "no part")
37+
if (!c.no_part)
3738
all_no_part = false;
3839
}
3940
if (all_no_part)
@@ -56,12 +57,16 @@ public static void OutputTSV(List<DesignatorGroup> groups, HeaderBlock header, s
5657
// component list
5758
foreach (Component c in g.comp_list)
5859
{
59-
if (c.footprint_normalized == "no part")
60+
if (c.no_part)
6061
continue;
6162

63+
string footprint = c.footprint_normalized;
64+
if (footprint == "")
65+
footprint = c.footprint;
6266
sw.WriteLine( "\t" + c.reference +
6367
"\t" + c.value +
64-
"\t" + c.footprint_normalized +
68+
"\t" + c.part_no +
69+
"\t" + footprint +
6570
"\t" + c.precision);
6671
}
6772
sw.WriteLine();
@@ -106,7 +111,7 @@ public static void OutputPDF(List<DesignatorGroup> groups, HeaderBlock header, s
106111
bool all_no_part = true;
107112
foreach (Component c in g.comp_list)
108113
{
109-
if (c.footprint_normalized != "no part")
114+
if (!c.no_part)
110115
all_no_part = false;
111116
}
112117
if (all_no_part)
@@ -134,7 +139,7 @@ public static void OutputPDF(List<DesignatorGroup> groups, HeaderBlock header, s
134139

135140
foreach (Component c in g.comp_list)
136141
{
137-
if (c.footprint_normalized == "no part")
142+
if (c.no_part)
138143
continue;
139144

140145
row = table.AddRow();

kibom/Program.cs

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading.Tasks;
66
using System.Xml;
77
using System.IO;
8+
using System.Reflection;
89

910
namespace kibom
1011
{
@@ -18,6 +19,9 @@ class Program
1819
{
1920
static void Main(string[] args)
2021
{
22+
Version v = Assembly.GetExecutingAssembly().GetName().Version;
23+
Console.WriteLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, @"Kibom {0}.{1} (build {2}.{3})", v.Major, v.Minor, v.Build, v.Revision));
24+
2125
string filename = "";
2226
string output_filename = "";
2327
string path = "";
@@ -37,6 +41,7 @@ static void Main(string[] args)
3741
XmlDocument doc = new XmlDocument();
3842
doc.Load(path + filename);
3943
ParseKicadXML(doc, path, filename, outputs, output_filename);
44+
Console.WriteLine("BOM generated.");
4045
}
4146

4247
static bool ParseArgs(string[] args, out string filename, out string path, out string outputs, out string output_filename)
@@ -58,7 +63,7 @@ static bool ParseArgs(string[] args, out string filename, out string path, out s
5863
Console.WriteLine("File not found.");
5964
return false;
6065
}
61-
path = Path.GetDirectoryName(filename);
66+
path = Path.GetDirectoryName(Path.GetFullPath(filename));
6267
if (!path.EndsWith("\\"))
6368
path += "\\";
6469
filename = Path.GetFileName(filename);
@@ -114,9 +119,10 @@ static bool ParseKicadXML(XmlDocument doc, string path, string filename, string
114119
return false;
115120

116121
// group components by designators and sort by value
117-
List<DesignatorGroup> groups = BuildDesignatorGroups(comp_list);
118-
SortDesignatorGroups(ref groups);
122+
List<DesignatorGroup> groups = Component.BuildDesignatorGroups(comp_list);
123+
Component.SortDesignatorGroups(ref groups);
119124
List<DesignatorGroup> merged_groups = Component.MergeComponents(groups);
125+
Component.SortComponents(ref merged_groups);
120126

121127
// sort groups alphabetically
122128
merged_groups.Sort((a, b) => a.designator.CompareTo(b.designator));
@@ -179,7 +185,13 @@ static List<Component> ParseComponents(XmlDocument doc)
179185
comp.value = node.SelectSingleNode("value").InnerText;
180186
comp.numeric_value = Component.ValueToNumeric(comp.value);
181187
comp.footprint = node.SelectSingleNode("footprint").InnerText;
188+
189+
// normalized footprint
182190
comp.footprint_normalized = Footprint.substitute(comp.footprint, true, true);
191+
if (comp.footprint_normalized == "no part")
192+
comp.no_part = true;
193+
if (comp.footprint.Contains(':')) // contrains library name
194+
comp.footprint = comp.footprint.Substring(comp.footprint.IndexOf(':') + 1);
183195

184196
// custom BOM fields
185197
XmlNode fields = node.SelectSingleNode("fields");
@@ -191,6 +203,7 @@ static List<Component> ParseComponents(XmlDocument doc)
191203
switch(field.Attributes["name"].Value.ToLower())
192204
{
193205
case "bom_footprint":
206+
//case "bom_partno":
194207
comp.footprint_normalized = field.InnerText;
195208
break;
196209

@@ -209,57 +222,22 @@ static List<Component> ParseComponents(XmlDocument doc)
209222
case "code":
210223
comp.code = field.InnerText;
211224
break;
225+
226+
case "bom_no_part":
227+
if (field.InnerText.ToLower() == "true")
228+
comp.no_part = true;
229+
break;
212230
}
213231
}
214232
}
215-
216-
if (!comp.footprint.Contains("no part")) // ignore pad only parts
233+
234+
if (!comp.no_part)
217235
comp_list.Add(comp);
218236

219237
//Console.WriteLine(comp.reference + "\t" + comp.value + "\t" + comp.footprint_normalized);
220238
}
221239

222240
return comp_list;
223241
}
224-
225-
static List<DesignatorGroup> BuildDesignatorGroups(List<Component> comp_list)
226-
{
227-
var groups = new List<DesignatorGroup>();
228-
229-
foreach(Component comp in comp_list)
230-
{
231-
bool found = false;
232-
for (int i = 0; i < groups.Count; i++)
233-
{
234-
if (groups[i].designator == comp.designator)
235-
{
236-
groups[i].comp_list.Add(comp);
237-
found = true;
238-
break;
239-
}
240-
}
241-
if (!found)
242-
{
243-
var new_group = new DesignatorGroup();
244-
new_group.designator = comp.designator;
245-
new_group.comp_list = new List<Component>();
246-
new_group.comp_list.Add(comp);
247-
groups.Add(new_group);
248-
}
249-
}
250-
251-
return groups;
252-
}
253-
254-
static void SortDesignatorGroups(ref List<DesignatorGroup> groups)
255-
{
256-
foreach (DesignatorGroup g in groups)
257-
{
258-
// sort by value
259-
//g.comp_list.Sort((a, b) => a.value.CompareTo(b.value));
260-
g.comp_list.Sort((a, b) => a.numeric_value.CompareTo(b.numeric_value));
261-
}
262-
}
263-
264242
}
265243
}

kibom/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.0.0.0")]
35+
[assembly: AssemblyVersion("0.2.*")]
3636
[assembly: AssemblyFileVersion("1.0.0.0")]

0 commit comments

Comments
 (0)