2 * gEDA - GNU Electronic Design Automation
3 * gerbv_stats.c -- a part of gerbv.
5 * Copyright (C) Stuart Brorson (sdb@cloud9.net)
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.
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.
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
24 /** \file gerb_stats.c
25 \brief Statistics generating functions for RS274X files
39 #include "gerb_stats.h"
42 /* DEBUG printing. #define DEBUG 1 in config.h to use this fcn. */
43 #define dprintf if(DEBUG) printf
45 /* ------------------------------------------------------- */
46 /** Allocates a new gerbv_stats structure
47 @return gerbv_stats pointer on success, NULL on ERROR */
49 gerbv_stats_new(void) {
52 gerbv_error_list_t
*error_list
;
53 gerbv_aperture_list_t
*aperture_list
;
54 gerbv_aperture_list_t
*D_code_list
;
56 /* Malloc space for new stats struct. Return NULL if error. */
57 if ((stats
= (gerbv_stats_t
*)g_malloc(sizeof(gerbv_stats_t
))) == NULL
) {
61 /* Set new stats struct to zero */
62 memset((void *)stats
, 0, sizeof(gerbv_stats_t
));
64 /* Initialize error list */
65 error_list
= gerbv_stats_new_error_list();
66 if (error_list
== NULL
)
67 GERB_FATAL_ERROR("malloc error_list failed\n");
68 stats
->error_list
= (gerbv_error_list_t
*) error_list
;
70 /* Initialize aperture list */
71 aperture_list
= gerbv_stats_new_aperture_list();
72 if (aperture_list
== NULL
)
73 GERB_FATAL_ERROR("malloc aperture_list failed\n");
74 stats
->aperture_list
= (gerbv_aperture_list_t
*) aperture_list
;
76 /* Initialize D codes list */
77 D_code_list
= gerbv_stats_new_aperture_list();
78 if (D_code_list
== NULL
)
79 GERB_FATAL_ERROR("malloc D_code_list failed\n");
80 stats
->D_code_list
= (gerbv_aperture_list_t
*) D_code_list
;
86 gerbv_destroy_error_list (gerbv_error_list_t
*errorList
) {
87 gerbv_error_list_t
*nextError
=errorList
,*tempError
;
90 tempError
= nextError
->next
;
91 g_free (nextError
->error_text
);
93 nextError
= tempError
;
98 gerbv_destroy_aperture_list (gerbv_aperture_list_t
*apertureList
) {
99 gerbv_aperture_list_t
*nextAperture
=apertureList
,*tempAperture
;
101 while (nextAperture
) {
102 tempAperture
= nextAperture
->next
;
103 g_free (nextAperture
);
104 nextAperture
= tempAperture
;
108 /* ------------------------------------------------------- */
110 gerbv_stats_destroy(gerbv_stats_t
*stats
) {
113 gerbv_destroy_error_list (stats
->error_list
);
114 gerbv_destroy_aperture_list (stats
->aperture_list
);
115 gerbv_destroy_aperture_list (stats
->D_code_list
);
120 /* ------------------------------------------------------- */
121 /*! This fcn is called with a two gerbv_stats_t structs:
122 * accum_stats and input_stats. Accum_stats holds
123 * a list of stats accumulated for
124 * all layers. This will be reported in the report window.
125 * Input_stats holds a list of the stats for one particular layer
126 * to be added to the accumulated list. */
128 gerbv_stats_add_layer(gerbv_stats_t
*accum_stats
,
129 gerbv_stats_t
*input_stats
,
132 dprintf("---> Entering gerbv_stats_add_layer ... \n");
134 gerbv_error_list_t
*error
;
135 gerbv_aperture_list_t
*aperture
;
136 gerbv_aperture_list_t
*D_code
;
138 accum_stats
->layer_count
++;
139 accum_stats
->G0
+= input_stats
->G0
;
140 accum_stats
->G1
+= input_stats
->G1
;
141 accum_stats
->G2
+= input_stats
->G2
;
142 accum_stats
->G3
+= input_stats
->G3
;
143 accum_stats
->G4
+= input_stats
->G4
;
144 accum_stats
->G10
+= input_stats
->G10
;
145 accum_stats
->G11
+= input_stats
->G11
;
146 accum_stats
->G12
+= input_stats
->G12
;
147 accum_stats
->G36
+= input_stats
->G36
;
148 accum_stats
->G37
+= input_stats
->G37
;
149 accum_stats
->G54
+= input_stats
->G54
;
150 accum_stats
->G55
+= input_stats
->G55
;
151 accum_stats
->G70
+= input_stats
->G70
;
152 accum_stats
->G71
+= input_stats
->G71
;
153 accum_stats
->G74
+= input_stats
->G74
;
154 accum_stats
->G75
+= input_stats
->G75
;
155 accum_stats
->G90
+= input_stats
->G90
;
156 accum_stats
->G91
+= input_stats
->G91
;
157 accum_stats
->G_unknown
+= input_stats
->G_unknown
;
159 accum_stats
->D1
+= input_stats
->D1
;
160 accum_stats
->D2
+= input_stats
->D2
;
161 accum_stats
->D3
+= input_stats
->D3
;
162 /* Create list of user-defined D codes from aperture list */
163 for (D_code
= input_stats
->D_code_list
;
165 D_code
= D_code
->next
) {
166 if (D_code
->number
!= -1) {
167 dprintf(" .... In gerbv_stats_add_layer, D code section, adding number = %d to accum_stats D list ...\n",
169 gerbv_stats_add_to_D_list(accum_stats
->D_code_list
,
171 dprintf(" .... In gerbv_stats_add_layer, D code section, calling increment_D_count with count %d ...\n",
173 gerbv_stats_increment_D_list_count(accum_stats
->D_code_list
,
176 accum_stats
->error_list
);
179 accum_stats
->D_unknown
+= input_stats
->D_unknown
;
180 accum_stats
->D_error
+= input_stats
->D_error
;
182 accum_stats
->M0
+= input_stats
->M0
;
183 accum_stats
->M1
+= input_stats
->M1
;
184 accum_stats
->M2
+= input_stats
->M2
;
185 accum_stats
->M_unknown
+= input_stats
->M_unknown
;
187 accum_stats
->X
+= input_stats
->X
;
188 accum_stats
->Y
+= input_stats
->Y
;
189 accum_stats
->I
+= input_stats
->I
;
190 accum_stats
->J
+= input_stats
->J
;
192 accum_stats
->star
+= input_stats
->star
;
193 accum_stats
->unknown
+= input_stats
->unknown
;
195 /* ==== Now deal with the error list ==== */
196 for (error
= input_stats
->error_list
;
198 error
= error
->next
) {
199 if (error
->error_text
!= NULL
) {
200 gerbv_stats_add_error(accum_stats
->error_list
,
207 /* ==== Now deal with the aperture list ==== */
208 for (aperture
= input_stats
->aperture_list
;
210 aperture
= aperture
->next
) {
211 if (aperture
->number
!= -1) {
212 gerbv_stats_add_aperture(accum_stats
->aperture_list
,
216 aperture
->parameter
);
220 dprintf("<---- .... Leaving gerbv_stats_add_layer. \n");
225 /* ------------------------------------------------------- */
227 gerbv_stats_new_error_list() {
228 gerbv_error_list_t
*error_list
;
230 /* Malloc space for new error_list struct. Return NULL if error. */
231 if ((error_list
= (gerbv_error_list_t
*)g_malloc(sizeof(gerbv_error_list_t
))) == NULL
) {
235 error_list
->layer
= -1;
236 error_list
->error_text
= NULL
;
237 error_list
->next
= NULL
;
242 /* ------------------------------------------------------- */
244 gerbv_stats_add_error(gerbv_error_list_t
*error_list_in
,
245 int layer
, const char *error_text
,
246 gerbv_message_type_t type
) {
248 gerbv_error_list_t
*error_list_new
;
249 gerbv_error_list_t
*error_last
= NULL
;
250 gerbv_error_list_t
*error
;
252 /* Replace embedded error messages */
254 case GERBV_MESSAGE_FATAL
:
255 GERB_FATAL_ERROR("%s",error_text
);
257 case GERBV_MESSAGE_ERROR
:
258 GERB_COMPILE_ERROR("%s",error_text
);
260 case GERBV_MESSAGE_WARNING
:
261 GERB_COMPILE_WARNING("%s",error_text
);
263 case GERBV_MESSAGE_NOTE
:
267 /* First handle case where this is the first list element */
268 if (error_list_in
->error_text
== NULL
) {
269 error_list_in
->layer
= layer
;
270 error_list_in
->error_text
= g_strdup_printf("%s", error_text
);
271 error_list_in
->type
= type
;
272 error_list_in
->next
= NULL
;
276 /* Next check to see if this error is already in the list */
277 for(error
= error_list_in
; error
!= NULL
; error
= error
->next
) {
278 if ((strcmp(error
->error_text
, error_text
) == 0) &&
279 (error
->layer
== layer
) ) {
280 return; /* This error text is already in the error list */
282 error_last
= error
; /* point to last element in error list */
284 /* This error text is unique. Therefore, add it to the list */
286 /* Now malloc space for new error list element */
287 error_list_new
= (gerbv_error_list_t
*) g_malloc(sizeof(gerbv_error_list_t
));
288 if (error_list_new
== NULL
) {
289 GERB_FATAL_ERROR("malloc error_list failed\n");
292 /* Set member elements */
293 error_list_new
->layer
= layer
;
294 error_list_new
->error_text
= g_strdup_printf("%s", error_text
);
295 error_list_new
->type
= type
;
296 error_list_new
->next
= NULL
;
297 error_last
->next
= error_list_new
;
302 /* ------------------------------------------------------- */
303 gerbv_aperture_list_t
*
304 gerbv_stats_new_aperture_list() {
305 gerbv_aperture_list_t
*aperture_list
;
308 dprintf("Mallocing new gerb aperture list\n");
309 /* Malloc space for new aperture_list struct. Return NULL if error. */
310 if ((aperture_list
= (gerbv_aperture_list_t
*)g_malloc(sizeof(gerbv_aperture_list_t
)))
315 dprintf(" Placing values in certain structs.\n");
316 aperture_list
->number
= -1;
317 aperture_list
->count
= 0;
318 aperture_list
->type
= 0;
319 for (i
= 0; i
<5; i
++) {
320 aperture_list
->parameter
[i
] = 0.0;
322 aperture_list
->next
= NULL
;
323 return aperture_list
;
327 /* ------------------------------------------------------- */
329 gerbv_stats_add_aperture(gerbv_aperture_list_t
*aperture_list_in
,
330 int layer
, int number
, gerbv_aperture_type_t type
,
331 double parameter
[5]) {
333 gerbv_aperture_list_t
*aperture_list_new
;
334 gerbv_aperture_list_t
*aperture_last
= NULL
;
335 gerbv_aperture_list_t
*aperture
;
338 dprintf(" ---> Entering gerbv_stats_add_aperture ....\n");
340 /* First handle case where this is the first list element */
341 if (aperture_list_in
->number
== -1) {
342 dprintf(" .... Adding first aperture to aperture list ... \n");
343 dprintf(" .... Aperture type = %d ... \n", type
);
344 aperture_list_in
->number
= number
;
345 aperture_list_in
->type
= type
;
346 aperture_list_in
->layer
= layer
;
348 aperture_list_in
->parameter
[i
] = parameter
[i
];
350 aperture_list_in
->next
= NULL
;
351 dprintf(" <--- .... Leaving gerbv_stats_add_aperture.\n");
355 /* Next check to see if this aperture is already in the list */
356 for(aperture
= aperture_list_in
;
358 aperture
= aperture
->next
) {
359 if ((aperture
->number
== number
) &&
360 (aperture
->layer
== layer
) ) {
361 dprintf(" .... This aperture is already in the list ... \n");
362 dprintf(" <--- .... Leaving gerbv_stats_add_aperture.\n");
365 aperture_last
= aperture
; /* point to last element in list */
367 /* This aperture number is unique. Therefore, add it to the list */
368 dprintf(" .... Adding another aperture to list ... \n");
369 dprintf(" .... Aperture type = %d ... \n", type
);
371 /* Now malloc space for new aperture list element */
372 aperture_list_new
= (gerbv_aperture_list_t
*) g_malloc(sizeof(gerbv_aperture_list_t
));
373 if (aperture_list_new
== NULL
) {
374 GERB_FATAL_ERROR("malloc aperture_list failed\n");
377 /* Set member elements */
378 aperture_list_new
->layer
= layer
;
379 aperture_list_new
->number
= number
;
380 aperture_list_new
->type
= type
;
381 aperture_list_new
->next
= NULL
;
383 aperture_list_new
->parameter
[i
] = parameter
[i
];
385 aperture_last
->next
= aperture_list_new
;
387 dprintf(" <--- .... Leaving gerbv_stats_add_aperture.\n");
392 /* ------------------------------------------------------- */
394 gerbv_stats_add_to_D_list(gerbv_aperture_list_t
*D_list_in
,
397 gerbv_aperture_list_t
*D_list
;
398 gerbv_aperture_list_t
*D_list_last
=NULL
;
399 gerbv_aperture_list_t
*D_list_new
;
401 dprintf(" ----> Entering add_to_D_list, numbr = %d\n", number
);
403 /* First handle case where this is the first list element */
404 if (D_list_in
->number
== -1) {
405 dprintf(" .... Adding first D code to D code list ... \n");
406 dprintf(" .... Aperture number = %d ... \n", number
);
407 D_list_in
->number
= number
;
408 D_list_in
->count
= 0;
409 D_list_in
->next
= NULL
;
410 dprintf(" <--- .... Leaving add_to_D_list.\n");
414 /* Look to see if this is already in list */
415 for(D_list
= D_list_in
;
417 D_list
= D_list
->next
) {
418 if (D_list
->number
== number
) {
419 dprintf(" .... Found in D list .... \n");
420 dprintf(" <--- .... Leaving add_to_D_list.\n");
423 D_list_last
= D_list
; /* point to last element in list */
426 /* This aperture number is unique. Therefore, add it to the list */
427 dprintf(" .... Adding another D code to D code list ... \n");
429 /* Malloc space for new aperture list element */
430 D_list_new
= (gerbv_aperture_list_t
*) g_malloc(sizeof(gerbv_aperture_list_t
));
431 if (D_list_new
== NULL
) {
432 GERB_FATAL_ERROR("malloc D_list failed\n");
435 /* Set member elements */
436 D_list_new
->number
= number
;
437 D_list_new
->count
= 0;
438 D_list_new
->next
= NULL
;
439 D_list_last
->next
= D_list_new
;
441 dprintf(" <--- .... Leaving add_to_D_list.\n");
446 /* ------------------------------------------------------- */
448 gerbv_stats_increment_D_list_count(gerbv_aperture_list_t
*D_list_in
,
451 gerbv_error_list_t
*error
) {
453 gerbv_aperture_list_t
*D_list
;
455 dprintf(" Entering inc_D_list_count, code = D%d, input count to add = %d\n", number
, count
);
457 /* Find D code in list and increment it */
458 for(D_list
= D_list_in
;
460 D_list
= D_list
->next
) {
461 if (D_list
->number
== number
) {
462 dprintf(" old count = %d\n", D_list
->count
);
463 D_list
->count
+= count
; /* Add to this aperture count, then return */
464 dprintf(" updated count = %d\n", D_list
->count
);
465 return 0; /* Return 0 for success */
469 /* This D number is not defined. Therefore, flag error */
470 dprintf(" .... Didn't find this D code in defined list .... \n");
471 dprintf(" <--- .... Leaving inc_D_list_count.\n");
472 gerbv_stats_add_error(error
,
474 "Undefined aperture number called out in D code.\n",
475 GERBV_MESSAGE_ERROR
);
476 return -1; /* Return -1 for failure */