gerbv
gerb_stats.c
Go to the documentation of this file.
1 /*
2  * gEDA - GNU Electronic Design Automation
3  * gerbv_stats.c -- a part of gerbv.
4  *
5  * Copyright (C) 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 <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34 
35 #include "common.h"
36 #include "gerb_stats.h"
37 
38 #undef DPRINTF
39 #define DPRINTF(...) do { if (DEBUG) printf(__VA_ARGS__); } while (0)
40 
41 /* ------------------------------------------------------- */
46 
47  gerbv_stats_t *stats;
49  gerbv_aperture_list_t *aperture_list;
50  gerbv_aperture_list_t *D_code_list;
51 
52  /* Malloc space for new stats struct. Return NULL if error. */
53  if (NULL == (stats = g_new0(gerbv_stats_t, 1))) {
54  return NULL;
55  }
56 
57  /* Initialize error list */
58  error_list = gerbv_stats_new_error_list();
59  if (error_list == NULL)
60  GERB_FATAL_ERROR("malloc error_list failed in %s()", __FUNCTION__);
61  stats->error_list = (gerbv_error_list_t *) error_list;
62 
63  /* Initialize aperture list */
64  aperture_list = gerbv_stats_new_aperture_list();
65  if (aperture_list == NULL)
66  GERB_FATAL_ERROR("malloc aperture_list failed in %s()", __FUNCTION__);
67  stats->aperture_list = (gerbv_aperture_list_t *) aperture_list;
68 
69  /* Initialize D codes list */
70  D_code_list = gerbv_stats_new_aperture_list();
71  if (D_code_list == NULL)
72  GERB_FATAL_ERROR("malloc D_code_list failed in %s()", __FUNCTION__);
73  stats->D_code_list = (gerbv_aperture_list_t *) D_code_list;
74 
75  return stats;
76 }
77 
78 void
79 gerbv_destroy_error_list (gerbv_error_list_t *errorList) {
80  gerbv_error_list_t *nextError=errorList,*tempError;
81 
82  while (nextError) {
83  tempError = nextError->next;
84  g_free (nextError->error_text);
85  g_free (nextError);
86  nextError = tempError;
87  }
88 }
89 
90 void
91 gerbv_destroy_aperture_list (gerbv_aperture_list_t *apertureList) {
92  gerbv_aperture_list_t *nextAperture=apertureList,*tempAperture;
93 
94  while (nextAperture) {
95  tempAperture = nextAperture->next;
96  g_free (nextAperture);
97  nextAperture = tempAperture;
98  }
99 }
100 
101 /* ------------------------------------------------------- */
102 void
104  if (stats == NULL)
105  return;
106  gerbv_destroy_error_list (stats->error_list);
107  gerbv_destroy_aperture_list (stats->aperture_list);
108  gerbv_destroy_aperture_list (stats->D_code_list);
109  g_free (stats);
110 }
111 
112 
113 /* ------------------------------------------------------- */
120 void
122  gerbv_stats_t *input_stats,
123  int this_layer) {
124 
125  DPRINTF("---> Entering gerbv_stats_add_layer ... \n");
126 
127  gerbv_error_list_t *error;
128  gerbv_aperture_list_t *aperture;
129  gerbv_aperture_list_t *D_code;
130 
131  accum_stats->layer_count++;
132  accum_stats->G0 += input_stats->G0;
133  accum_stats->G1 += input_stats->G1;
134  accum_stats->G2 += input_stats->G2;
135  accum_stats->G3 += input_stats->G3;
136  accum_stats->G4 += input_stats->G4;
137  accum_stats->G10 += input_stats->G10;
138  accum_stats->G11 += input_stats->G11;
139  accum_stats->G12 += input_stats->G12;
140  accum_stats->G36 += input_stats->G36;
141  accum_stats->G37 += input_stats->G37;
142  accum_stats->G54 += input_stats->G54;
143  accum_stats->G55 += input_stats->G55;
144  accum_stats->G70 += input_stats->G70;
145  accum_stats->G71 += input_stats->G71;
146  accum_stats->G74 += input_stats->G74;
147  accum_stats->G75 += input_stats->G75;
148  accum_stats->G90 += input_stats->G90;
149  accum_stats->G91 += input_stats->G91;
150  accum_stats->G_unknown += input_stats->G_unknown;
151 
152  accum_stats->D1 += input_stats->D1;
153  accum_stats->D2 += input_stats->D2;
154  accum_stats->D3 += input_stats->D3;
155  /* Create list of user-defined D codes from aperture list */
156  for (D_code = input_stats->D_code_list;
157  D_code != NULL;
158  D_code = D_code->next) {
159  if (D_code->number != -1) {
160  DPRINTF(" .... In gerbv_stats_add_layer, D code section, adding number = %d to accum_stats D list ...\n",
161  D_code->number);
162  gerbv_stats_add_to_D_list(accum_stats->D_code_list,
163  D_code->number);
164  DPRINTF(" .... In gerbv_stats_add_layer, D code section, calling increment_D_count with count %d ...\n",
165  D_code->count);
166  gerbv_stats_increment_D_list_count(accum_stats->D_code_list,
167  D_code->number,
168  D_code->count,
169  accum_stats->error_list);
170  }
171  }
172  accum_stats->D_unknown += input_stats->D_unknown;
173  accum_stats->D_error += input_stats->D_error;
174 
175  accum_stats->M0 += input_stats->M0;
176  accum_stats->M1 += input_stats->M1;
177  accum_stats->M2 += input_stats->M2;
178  accum_stats->M_unknown += input_stats->M_unknown;
179 
180  accum_stats->X += input_stats->X;
181  accum_stats->Y += input_stats->Y;
182  accum_stats->I += input_stats->I;
183  accum_stats->J += input_stats->J;
184 
185  accum_stats->star += input_stats->star;
186  accum_stats->unknown += input_stats->unknown;
187 
188  /* ==== Now deal with the error list ==== */
189  for (error = input_stats->error_list;
190  error != NULL;
191  error = error->next) {
192  if (error->error_text != NULL) {
193  gerbv_stats_add_error(accum_stats->error_list,
194  this_layer,
195  error->error_text,
196  error->type);
197  }
198  }
199 
200  /* ==== Now deal with the aperture list ==== */
201  for (aperture = input_stats->aperture_list;
202  aperture != NULL;
203  aperture = aperture->next) {
204  if (aperture->number != -1) {
205  gerbv_stats_add_aperture(accum_stats->aperture_list,
206  this_layer,
207  aperture->number,
208  aperture->type,
209  aperture->parameter);
210  }
211  }
212 
213  DPRINTF("<---- .... Leaving gerbv_stats_add_layer. \n");
214 
215  return;
216 }
217 
218 /* ------------------------------------------------------- */
220 gerbv_stats_new_error_list() {
222 
223  /* Malloc space for new error_list struct. Return NULL if error. */
224  if (NULL == (error_list = g_new(gerbv_error_list_t, 1))) {
225  return NULL;
226  }
227 
228  error_list->layer = -1;
229  error_list->error_text = NULL;
230  error_list->next = NULL;
231  return error_list;
232 }
233 
234 /* ------------------------------------------------------- */
235 void
236 gerbv_stats_printf(gerbv_error_list_t *list, gerbv_message_type_t type,
237  int layer, const char *text, ...)
238 {
239  gchar *str;
240  va_list args;
241 
242  va_start(args, text);
243  str = g_strdup_vprintf(text, args);
244  va_end(args);
245  gerbv_stats_add_error(list, layer, str, type);
246  g_free(str);
247 }
248 
253 /* ------------------------------------------------------- */
254 int
256 {
257  int i = 0;
258  char *ec = (char *)&i;
259 
260  ec[0] = '\\';
261 
262  switch (c) {
263  case '\0':
264  ec[1] = '0';
265  break;
266  case '\a':
267  ec[1] = 'a';
268  break;
269  case '\b':
270  ec[1] = 'b';
271  break;
272  case '\f':
273  ec[1] = 'f';
274  break;
275  case '\n':
276  ec[1] = 'n';
277  break;
278  case '\r':
279  ec[1] = 'r';
280  break;
281  case '\t':
282  ec[1] = 't';
283  break;
284  case '\v':
285  ec[1] = 'v';
286  break;
287  case '\\':
288  ec[1] = '\\';
289  break;
290  case '"':
291  ec[1] = '"';
292  break;
293  default:
294  ec[0] = c;
295  }
296 
297  return i;
298 }
299 
300 /* ------------------------------------------------------- */
301 void
302 gerbv_stats_add_error(gerbv_error_list_t *error_list_in,
303  int layer, const char *error_text,
304  gerbv_message_type_t type) {
305 
306  gerbv_error_list_t *error_list_new;
307  gerbv_error_list_t *error_last = NULL;
308  gerbv_error_list_t *error;
309 
310  /* Replace embedded error messages */
311  switch (type) {
312  case GERBV_MESSAGE_FATAL:
313  GERB_FATAL_ERROR("%s",error_text);
314  break;
315  case GERBV_MESSAGE_ERROR:
316  GERB_COMPILE_ERROR("%s",error_text);
317  break;
319  GERB_COMPILE_WARNING("%s",error_text);
320  break;
321  case GERBV_MESSAGE_NOTE:
322  GERB_NOTE("%s", error_text);
323  break;
324  }
325 
326  /* First handle case where this is the first list element */
327  if (error_list_in->error_text == NULL) {
328  error_list_in->layer = layer;
329  error_list_in->error_text = g_strdup_printf("%s", error_text);
330  error_list_in->type = type;
331  error_list_in->next = NULL;
332  return;
333  }
334 
335  /* Next check to see if this error is already in the list */
336  for(error = error_list_in; error != NULL; error = error->next) {
337  if ((strcmp(error->error_text, error_text) == 0) &&
338  (error->layer == layer) ) {
339  return; /* This error text is already in the error list */
340  }
341  error_last = error; /* point to last element in error list */
342  }
343  /* This error text is unique. Therefore, add it to the list */
344 
345  /* Now malloc space for new error list element */
346  if (NULL == (error_list_new = g_new(gerbv_error_list_t, 1))) {
347  GERB_FATAL_ERROR("malloc error_list failed in %s()", __FUNCTION__);
348  }
349 
350  /* Set member elements */
351  error_list_new->layer = layer;
352  error_list_new->error_text = g_strdup_printf("%s", error_text);
353  error_list_new->type = type;
354  error_list_new->next = NULL;
355  error_last->next = error_list_new;
356 
357  return;
358 }
359 
360 /* ------------------------------------------------------- */
361 gerbv_aperture_list_t *
362 gerbv_stats_new_aperture_list() {
363  gerbv_aperture_list_t *aperture_list;
364  int i;
365 
366  DPRINTF("Mallocing new gerb aperture list\n");
367  /* Malloc space for new aperture_list struct. Return NULL if error. */
368  if (NULL == (aperture_list = g_new(gerbv_aperture_list_t, 1))) {
369  DPRINTF("malloc new gerb aperture list failed in %s()\n", __FUNCTION__);
370  return NULL;
371  }
372 
373  DPRINTF(" Placing values in certain structs.\n");
374  aperture_list->number = -1;
375  aperture_list->count = 0;
376  aperture_list->type = 0;
377  for (i = 0; i<5; i++) {
378  aperture_list->parameter[i] = 0.0;
379  }
380  aperture_list->next = NULL;
381  return aperture_list;
382 }
383 
384 
385 /* ------------------------------------------------------- */
386 void
387 gerbv_stats_add_aperture(gerbv_aperture_list_t *aperture_list_in,
388  int layer, int number, gerbv_aperture_type_t type,
389  double parameter[5]) {
390 
391  gerbv_aperture_list_t *aperture_list_new;
392  gerbv_aperture_list_t *aperture_last = NULL;
393  gerbv_aperture_list_t *aperture;
394  int i;
395 
396  DPRINTF(" ---> Entering gerbv_stats_add_aperture ....\n");
397 
398  /* First handle case where this is the first list element */
399  if (aperture_list_in->number == -1) {
400  DPRINTF(" .... Adding first aperture to aperture list ... \n");
401  DPRINTF(" .... Aperture type = %d ... \n", type);
402  aperture_list_in->number = number;
403  aperture_list_in->type = type;
404  aperture_list_in->layer = layer;
405  for(i=0; i<5; i++) {
406  aperture_list_in->parameter[i] = parameter[i];
407  }
408  aperture_list_in->next = NULL;
409  DPRINTF(" <--- .... Leaving gerbv_stats_add_aperture.\n");
410  return;
411  }
412 
413  /* Next check to see if this aperture is already in the list */
414  for(aperture = aperture_list_in;
415  aperture != NULL;
416  aperture = aperture->next) {
417  if ((aperture->number == number) &&
418  (aperture->layer == layer) ) {
419  DPRINTF(" .... This aperture is already in the list ... \n");
420  DPRINTF(" <--- .... Leaving gerbv_stats_add_aperture.\n");
421  return;
422  }
423  aperture_last = aperture; /* point to last element in list */
424  }
425  /* This aperture number is unique. Therefore, add it to the list */
426  DPRINTF(" .... Adding another aperture to list ... \n");
427  DPRINTF(" .... Aperture type = %d ... \n", type);
428 
429  /* Now malloc space for new aperture list element */
430  if (NULL == (aperture_list_new = g_new(gerbv_aperture_list_t, 1))) {
431  GERB_FATAL_ERROR("malloc aperture_list failed in %s()", __FUNCTION__);
432  }
433 
434  /* Set member elements */
435  aperture_list_new->layer = layer;
436  aperture_list_new->number = number;
437  aperture_list_new->type = type;
438  aperture_list_new->next = NULL;
439  for(i=0; i<5; i++) {
440  aperture_list_new->parameter[i] = parameter[i];
441  }
442  aperture_last->next = aperture_list_new;
443 
444  DPRINTF(" <--- .... Leaving gerbv_stats_add_aperture.\n");
445 
446  return;
447 }
448 
449 /* ------------------------------------------------------- */
450 void
451 gerbv_stats_add_to_D_list(gerbv_aperture_list_t *D_list_in,
452  int number) {
453 
454  gerbv_aperture_list_t *D_list;
455  gerbv_aperture_list_t *D_list_last=NULL;
456  gerbv_aperture_list_t *D_list_new;
457 
458  DPRINTF(" ----> Entering add_to_D_list, numbr = %d\n", number);
459 
460  /* First handle case where this is the first list element */
461  if (D_list_in->number == -1) {
462  DPRINTF(" .... Adding first D code to D code list ... \n");
463  DPRINTF(" .... Aperture number = %d ... \n", number);
464  D_list_in->number = number;
465  D_list_in->count = 0;
466  D_list_in->next = NULL;
467  DPRINTF(" <--- .... Leaving add_to_D_list.\n");
468  return;
469  }
470 
471  /* Look to see if this is already in list */
472  for(D_list = D_list_in;
473  D_list != NULL;
474  D_list = D_list->next) {
475  if (D_list->number == number) {
476  DPRINTF(" .... Found in D list .... \n");
477  DPRINTF(" <--- .... Leaving add_to_D_list.\n");
478  return;
479  }
480  D_list_last = D_list; /* point to last element in list */
481  }
482 
483  /* This aperture number is unique. Therefore, add it to the list */
484  DPRINTF(" .... Adding another D code to D code list ... \n");
485 
486  /* Malloc space for new aperture list element */
487  if (NULL == (D_list_new = g_new(gerbv_aperture_list_t, 1))) {
488  GERB_FATAL_ERROR("malloc D_list failed in %s()", __FUNCTION__);
489  }
490 
491  /* Set member elements */
492  D_list_new->number = number;
493  D_list_new->count = 0;
494  D_list_new->next = NULL;
495  D_list_last->next = D_list_new;
496 
497  DPRINTF(" <--- .... Leaving add_to_D_list.\n");
498 
499  return;
500 }
501 
502 /* ------------------------------------------------------- */
503 int
504 gerbv_stats_increment_D_list_count(gerbv_aperture_list_t *D_list_in,
505  int number,
506  int count,
507  gerbv_error_list_t *error) {
508 
509  gerbv_aperture_list_t *D_list;
510 
511  DPRINTF(" Entering inc_D_list_count, code = D%d, input count to add = %d\n", number, count);
512 
513  /* Find D code in list and increment it */
514  for(D_list = D_list_in;
515  D_list != NULL;
516  D_list = D_list->next) {
517  if (D_list->number == number) {
518  DPRINTF(" old count = %d\n", D_list->count);
519  D_list->count += count; /* Add to this aperture count, then return */
520  DPRINTF(" updated count = %d\n", D_list->count);
521  return 0; /* Return 0 for success */
522  }
523  }
524 
525  /* This D number is not defined. Therefore, flag error */
526  DPRINTF(" .... Didn't find this D code in defined list .... \n");
527  DPRINTF(" <--- .... Leaving inc_D_list_count.\n");
528 
529  gerbv_stats_printf(error, GERBV_MESSAGE_ERROR, -1,
530  _("Undefined aperture number called out in D code"));
531 
532  return -1; /* Return -1 for failure */
533 }
534 
int gerbv_escape_char_return_int(char c)
Escape special ASCII char (' ', '\0').
Definition: gerb_stats.c:255
gerbv_stats_t * gerbv_stats_new(void)
Allocates a new gerbv_stats structure.
Definition: gerb_stats.c:45
void gerbv_stats_add_layer(gerbv_stats_t *accum_stats, gerbv_stats_t *input_stats, int this_layer)
Definition: gerb_stats.c:121
void gerbv_stats_destroy(gerbv_stats_t *stats)
Definition: gerb_stats.c:103
Header info for the statistics generating functions for RS274X files.
The main header file for the libgerbv library.
gerbv_message_type_t
Definition: gerbv.h:149
@ GERBV_MESSAGE_ERROR
Definition: gerbv.h:150
@ GERBV_MESSAGE_NOTE
Definition: gerbv.h:152
@ GERBV_MESSAGE_FATAL
Definition: gerbv.h:149
@ GERBV_MESSAGE_WARNING
Definition: gerbv.h:151
gerbv_aperture_type_t
Definition: gerbv.h:158