gerbv  2.6A
drill_stats.c
Go to the documentation of this file.
1 /*
2  * gEDA - GNU Electronic Design Automation
3  * drill_stats.c -- a part of gerbv.
4  *
5  * Copyright (C) 2007 Stuart Brorson (sdb@cloud9.net)
6  *
7  * $Id$
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
22  */
23 
29 #include "gerbv.h"
30 
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <math.h>
35 
36 #include "common.h"
37 #include "drill_stats.h"
38 
39 #define dprintf if(DEBUG) printf
40 
41 
42 /* ------------------------------------------------------- */
47 
48  gerbv_drill_stats_t *stats;
51 
52  /* Malloc space for new stats struct. Return NULL if error. */
53  if ((stats = (gerbv_drill_stats_t *)g_malloc(sizeof(gerbv_drill_stats_t))) == NULL) {
54  return NULL;
55  }
56 
57  /* Set new stats struct to zero */
58  memset((void *)stats, 0, sizeof(gerbv_drill_stats_t));
59 
60  /* Initialize drill list */
61  drill_list = gerbv_drill_stats_new_drill_list();
62  if (drill_list == NULL)
63  GERB_FATAL_ERROR(_("malloc drill_list failed"));
64  stats->drill_list = (gerbv_drill_list_t *) drill_list;
65 
66  /* Initialize error list */
67  error_list = gerbv_drill_stats_new_error_list();
68  if (error_list == NULL)
69  GERB_FATAL_ERROR(_("malloc error_list failed"));
70  stats->error_list = (gerbv_error_list_t *) error_list;
71 
72  stats->detect = NULL;
73 
74  return stats;
75 }
76 
77 void
78 gerbv_drill_destroy_error_list (gerbv_error_list_t *errorList) {
79  gerbv_error_list_t *nextError=errorList,*tempError;
80 
81  while (nextError) {
82  tempError = nextError->next;
83  g_free (nextError->error_text);
84  g_free (nextError);
85  nextError = tempError;
86  }
87 }
88 
89 void
90 gerbv_drill_destroy_drill_list (gerbv_drill_list_t *apertureList) {
91  gerbv_drill_list_t *nextAperture=apertureList,*tempAperture;
92 
93  while (nextAperture) {
94  tempAperture = nextAperture->next;
95  g_free(nextAperture->drill_unit);
96  g_free (nextAperture);
97  nextAperture = tempAperture;
98  }
99 }
100 
101 void
103  if (stats == NULL)
104  return;
105  gerbv_drill_destroy_error_list (stats->error_list);
106  gerbv_drill_destroy_drill_list (stats->drill_list);
107  g_free (stats);
108 }
109 
110 /* ------------------------------------------------------- */
111 void
113  gerbv_drill_stats_t *input_stats,
114  int this_layer) {
115 
116  gerbv_drill_list_t *drill;
117  gerbv_error_list_t *error;
118  char *tmps, *tmps2;
119 
120  dprintf("---> Entering gerbv_drill_stats_add_layer ..... \n");
121 
122  accum_stats->layer_count++;
123 
124  accum_stats->comment += input_stats->comment;
125  /* F codes go here */
126 
127  accum_stats->G00 += input_stats->G00;
128  accum_stats->G01 += input_stats->G01;
129  accum_stats->G02 += input_stats->G02;
130  accum_stats->G03 += input_stats->G03;
131  accum_stats->G04 += input_stats->G04;
132  accum_stats->G05 += input_stats->G05;
133  accum_stats->G85 += input_stats->G85;
134  accum_stats->G90 += input_stats->G90;
135  accum_stats->G91 += input_stats->G91;
136  accum_stats->G93 += input_stats->G93;
137  accum_stats->G_unknown += input_stats->G_unknown;
138 
139  accum_stats->M00 += input_stats->M00;
140  accum_stats->M01 += input_stats->M01;
141  accum_stats->M18 += input_stats->M18;
142  accum_stats->M25 += input_stats->M25;
143  accum_stats->M30 += input_stats->M30;
144  accum_stats->M31 += input_stats->M31;
145  accum_stats->M45 += input_stats->M45;
146  accum_stats->M47 += input_stats->M47;
147  accum_stats->M48 += input_stats->M48;
148  accum_stats->M71 += input_stats->M71;
149  accum_stats->M72 += input_stats->M72;
150  accum_stats->M95 += input_stats->M95;
151  accum_stats->M97 += input_stats->M97;
152  accum_stats->M98 += input_stats->M98;
153  accum_stats->M_unknown += input_stats->M_unknown;
154 
155  accum_stats->R += input_stats->R;
156 
157  /* ==== Now deal with the drill list ==== */
158  for (drill = input_stats->drill_list;
159  drill != NULL;
160  drill = drill->next) {
161  dprintf(" In gerbv_drill_stats_add_layer, adding drill_num = %d to list\n",
162  drill->drill_num);
163  /* First add this input drill to the accumulated list.
164  * Drills already in accum list will not be added. */
165  drill_stats_add_to_drill_list(accum_stats->drill_list,
166  drill->drill_num,
167  drill->drill_size,
168  drill->drill_unit);
169 
170  /* Now add count of input drill to accum list */
171  dprintf(" adding count %d of drills for drill %d\n",
172  drill->drill_count, drill->drill_num);
173  drill_stats_add_to_drill_counter(accum_stats->drill_list,
174  drill->drill_num,
175  drill->drill_count);
176  accum_stats->total_count += drill->drill_count;
177  }
178 
179  /* ==== Now deal with the error list ==== */
180  for (error = input_stats->error_list;
181  error != NULL;
182  error = error->next) {
183  if (error->error_text != NULL) {
184  drill_stats_add_error(accum_stats->error_list,
185  this_layer,
186  error->error_text,
187  error->type);
188  }
189  }
190 
191  /* ==== Now deal with the misc header stuff ==== */
192  tmps = NULL;
193  tmps2 = NULL;
194  if (input_stats->detect) {
195  tmps2 = g_strdup_printf (_("Broken tool detect %s (layer %d)"), input_stats->detect, this_layer);
196  }
197  if (accum_stats->detect) {
198  if (tmps2) {
199  tmps = g_strdup_printf ("%s\n%s", accum_stats->detect, tmps2);
200  g_free (accum_stats->detect);
201  accum_stats->detect = NULL;
202  }
203  } else {
204  if (tmps2) {
205  tmps = g_strdup_printf ("%s", tmps2);
206  }
207  }
208  if (tmps2) {
209  g_free (tmps2);
210  }
211  if (tmps != NULL) {
212  accum_stats->detect = tmps;
213  }
214 
215  for (error = input_stats->error_list;
216  error != NULL;
217  error = error->next) {
218  if (error->error_text != NULL) {
219  drill_stats_add_error(accum_stats->error_list,
220  this_layer,
221  error->error_text,
222  error->type);
223  }
224  }
225 
226 
227  dprintf("<--- .... Leaving gerbv_drill_stats_add_layer.\n");
228 
229  return;
230 }
231 
232 
233 /* ------------------------------------------------------- */
234 gboolean
235 drill_stats_in_drill_list(gerbv_drill_list_t *drill_list_in,
236  int drill_num_in) {
237  gerbv_drill_list_t *drill;
238  for(drill = drill_list_in; drill != NULL; drill = drill->next) {
239  if (drill_num_in == drill->drill_num) {
240  return TRUE;
241  }
242  }
243  return FALSE;
244 
245 }
246 
247 /* ------------------------------------------------------- */
249 gerbv_drill_stats_new_drill_list() {
251 
252  /* Malloc space for new drill_list struct. Return NULL if error. */
253  if ((drill_list = (gerbv_drill_list_t *)g_malloc(sizeof(gerbv_drill_list_t))) == NULL) {
254  return NULL;
255  }
256 
257  drill_list->drill_count = 0;
258  drill_list->drill_num = -1; /* default val */
259  drill_list->drill_size = 0.0;
260  drill_list->drill_unit = NULL;
261  drill_list->next = NULL;
262  return drill_list;
263 }
264 
265 
266 /* ------------------------------------------------------- */
267 void
268 drill_stats_add_to_drill_list(gerbv_drill_list_t *drill_list_in,
269  int drill_num_in, double drill_size_in,
270  char *drill_unit_in) {
271 
272  gerbv_drill_list_t *drill_list_new;
273  gerbv_drill_list_t *drill;
274  gerbv_drill_list_t *drill_last = NULL;
275 
276  dprintf ("%s(%p, %d, %g, \"%s\")\n", __FUNCTION__, drill_list_in, drill_num_in,
277  drill_size_in, drill_unit_in);
278 
279  dprintf(" ---> Entering drill_stats_add_to_drill_list, first drill_num in list = %d ...\n",
280  drill_list_in->drill_num);
281 
282  /* First check for empty list. If empty, then just add this drill */
283  if (drill_list_in->drill_num == -1) {
284  dprintf(" .... In drill_stats_add_to_drill_list, adding first drill, no %d\n",
285  drill_num_in);
286  drill_list_in->drill_num = drill_num_in;
287  drill_list_in->drill_size = drill_size_in;
288  drill_list_in->drill_count = 0;
289  drill_list_in->drill_unit = g_strdup_printf("%s", drill_unit_in);
290  drill_list_in->next = NULL;
291  return;
292  }
293  /* Else check to see if this drill is already in the list */
294  for(drill = drill_list_in;
295  drill != NULL;
296  drill = (gerbv_drill_list_t *) drill->next) {
297  dprintf("checking this drill_num %d against that in list %d.\n",
298  drill_num_in, drill->drill_num);
299  if (drill_num_in == drill->drill_num) {
300  dprintf(" .... In drill_stats_add_to_drill_list, drill no %d already in list\n",
301  drill_num_in);
302  return; /* Found it in list, so return */
303  }
304  drill_last = drill;
305  }
306 
307  /* Now malloc space for new drill list element */
308  drill_list_new = (gerbv_drill_list_t *) g_malloc(sizeof(gerbv_drill_list_t));
309  if (drill_list_new == NULL) {
310  GERB_FATAL_ERROR(_("malloc format failed"));
311  }
312 
313  /* Now set various parameters based upon calling args */
314  dprintf(" .... In drill_stats_add_to_drill_list, adding new drill, no %d\n",
315  drill_num_in);
316  drill_list_new->drill_num = drill_num_in;
317  drill_list_new->drill_size = drill_size_in;
318  drill_list_new->drill_count = 0;
319  drill_list_new->drill_unit = g_strdup_printf("%s", drill_unit_in);
320  drill_list_new->next = NULL;
321  drill_last->next = drill_list_new;
322 
323  dprintf(" <---- ... leaving drill_stats_add_to_drill_list.\n");
324  return;
325 }
326 
327 /* ------------------------------------------------------- */
328 void
329 drill_stats_modify_drill_list(gerbv_drill_list_t *drill_list_in,
330  int drill_num_in, double drill_size_in,
331  char *drill_unit_in) {
332 
333  gerbv_drill_list_t *drill;
334 
335  dprintf(" ---> Entering drill_stats_modify_drill_list, first drill_num in list = %d ...\n",
336  drill_list_in->drill_num);
337 
338  /* Look for this drill num in list */
339  for(drill = drill_list_in;
340  drill != NULL;
341  drill = (gerbv_drill_list_t *) drill->next) {
342  dprintf("checking this drill_num %d against that in list %d.\n",
343  drill_num_in, drill->drill_num);
344  if (drill_num_in == drill->drill_num) {
345  dprintf(" .... Found it, now update it ....\n");
346  drill->drill_size = drill_size_in;
347  if (drill->drill_unit)
348  g_free(drill->drill_unit);
349  drill->drill_unit = g_strdup_printf("%s", drill_unit_in);
350  dprintf(" <---- ... Modified drill. leaving drill_stats_modify_drill_list.\n");
351  return;
352  }
353  }
354  dprintf(" <---- ... Did not find drill. leaving drill_stats_modify_drill_list.\n");
355  return;
356 }
357 
358 /* ------------------------------------------------------- */
359 void
360 drill_stats_increment_drill_counter(gerbv_drill_list_t *drill_list_in,
361  int drill_num_in) {
362 
363  dprintf(" ----> Entering drill_stats_increment_drill_counter......\n");
364  /* First check to see if this drill is already in the list */
365  gerbv_drill_list_t *drill;
366  for(drill = drill_list_in; drill != NULL; drill = drill->next) {
367  if (drill_num_in == drill->drill_num) {
368  drill->drill_count++;
369  dprintf(" .... incrementing drill count. drill_num = %d, drill_count = %d.\n",
370  drill_list_in->drill_num, drill->drill_count);
371  dprintf(" <---- .... Leaving drill_stats_increment_drill_counter after incrementing counter.\n");
372  return;
373  }
374  }
375  dprintf(" <---- .... Leaving drill_stats_increment_drill_counter without incrementing any counter.\n");
376 
377 }
378 
379 /* ------------------------------------------------------- */
380 void
381 drill_stats_add_to_drill_counter(gerbv_drill_list_t *drill_list_in,
382  int drill_num_in,
383  int increment) {
384 
385  gerbv_drill_list_t *drill;
386  for(drill = drill_list_in; drill != NULL; drill = drill->next) {
387  if (drill_num_in == drill->drill_num) {
388  dprintf(" In drill_stats_add_to_drill_counter, adding increment = %d drills to drill list\n", increment);
389  drill->drill_count += increment;
390  return;
391  }
392  }
393 }
394 
395 
396 /* ------------------------------------------------------- */
398 gerbv_drill_stats_new_error_list() {
400 
401  /* Malloc space for new error_list struct. Return NULL if error. */
402  if ((error_list = (gerbv_error_list_t *)g_malloc(sizeof(gerbv_error_list_t))) == NULL) {
403  return NULL;
404  }
405 
406  error_list->layer = -1;
407  error_list->error_text = NULL;
408  error_list->next = NULL;
409  return error_list;
410 }
411 
412 
413 
414 /* ------------------------------------------------------- */
415 void
416 drill_stats_add_error(gerbv_error_list_t *error_list_in,
417  int layer, const char *error_text,
418  gerbv_message_type_t type) {
419 
420  gerbv_error_list_t *error_list_new;
421  gerbv_error_list_t *error_last = NULL;
422  gerbv_error_list_t *error;
423 
424  dprintf(" ----> Entering drill_stats_add_error......\n");
425 
426  /* Replace embedded error messages */
427  switch (type) {
428  case GERBV_MESSAGE_FATAL:
429  GERB_FATAL_ERROR("%s",error_text);
430  break;
431  case GERBV_MESSAGE_ERROR:
432  GERB_COMPILE_ERROR("%s",error_text);
433  break;
435  GERB_COMPILE_WARNING("%s",error_text);
436  break;
437  case GERBV_MESSAGE_NOTE:
438  break;
439  }
440 
441 
442  /* First handle case where this is the first list element */
443  if (error_list_in->error_text == NULL) {
444  error_list_in->layer = layer;
445  error_list_in->error_text = g_strdup_printf("%s", error_text);
446  error_list_in->type = type;
447  error_list_in->next = NULL;
448  dprintf(" <---- .... Leaving drill_stats_add_error after adding first error message.\n");
449  return;
450  }
451 
452  /* Next check to see if this error is already in the list */
453  for(error = error_list_in; error != NULL; error = error->next) {
454  if ((strcmp(error->error_text, error_text) == 0) &&
455  (error->layer == layer) ) {
456  return; /* This error text is already in the error list */
457  }
458  error_last = error; /* point to last element in error list */
459  }
460  /* This error text is unique. Therefore, add it to the list */
461 
462  /* Now malloc space for new error list element */
463  error_list_new = (gerbv_error_list_t *) g_malloc(sizeof(gerbv_error_list_t));
464  if (error_list_new == NULL) {
465  GERB_FATAL_ERROR(_("malloc error_list failed"));
466  }
467 
468  /* Set member elements */
469  error_list_new->layer = layer;
470  error_list_new->error_text = g_strdup_printf("%s", error_text);
471  error_list_new->type = type;
472  error_list_new->next = NULL;
473  error_last->next = error_list_new;
474 
475  dprintf(" <---- .... Leaving drill_stats_add_error after adding new error message.\n");
476  return;
477 
478 }