47 #include <sys/types.h>
62 #define DPRINTF(...) do { if (DEBUG) printf(__VA_ARGS__); } while (0)
65 #define DRILL_READ_DOUBLE_SIZE 32
68 DRILL_NONE, DRILL_HEADER, DRILL_DATA
69 } drill_file_section_t;
72 DRILL_MODE_ABSOLUTE, DRILL_MODE_INCREMENTAL
73 } drill_coordinate_mode_t;
83 typedef struct drill_pattern_entry {
90 } drill_pattern_entry_t;
92 typedef struct drill_state {
96 drill_file_section_t curr_section;
97 drill_coordinate_mode_t coordinate_mode;
107 number_fmt_t number_format, header_number_format;
109 number_fmt_t backup_number_format;
128 drill_g_code_t route_mode;
137 gboolean found_arc_radius;
141 GArray *pattern_buffer;
151 static drill_g_code_t drill_parse_G_code(gerb_file_t *fd,
153 static drill_m_code_t drill_parse_M_code(gerb_file_t *fd, drill_state_t *state,
155 static int drill_parse_T_code(gerb_file_t *fd, drill_state_t *state,
157 static int drill_parse_header_is_metric(gerb_file_t *fd, drill_state_t *state,
159 static int drill_parse_header_is_metric_comment(gerb_file_t *fd, drill_state_t *state,
161 static int drill_parse_header_is_inch(gerb_file_t *fd, drill_state_t *state,
163 static int drill_parse_header_is_ici(gerb_file_t *fd, drill_state_t *state,
165 static void drill_parse_coordinate(gerb_file_t *fd,
char firstchar,
167 unsigned int file_line);
168 static drill_state_t *new_state(
void);
170 drill_state_t *state,
172 double prev_x,
double prev_y);
174 drill_state_t *state,
177 double prev_x,
double prev_y);
179 drill_state_t *state,
182 double start_x,
double start_y,
183 double center_x,
double center_y,
185 static double read_double(gerb_file_t *fd, number_fmt_t fmt,
187 static void eat_line(gerb_file_t *fd);
188 static void eat_whitespace(gerb_file_t *fd);
189 static char *get_line(gerb_file_t *fd);
190 static int file_check_str(gerb_file_t *fd,
const char *str);
203 static const char *suppression_list[] = {
210 static const char *units_list[] = {
226 static gerbv_HID_Attribute drill_attribute_list[] = {
228 {N_(
"autodetect"), N_(
"Try to autodetect the file format"),
229 HID_Boolean, 0, 0, {1, 0, 0}, 0, 0, 0},
231 {N_(
"zero_suppression"), N_(
"Zero suppression"),
232 HID_Enum, 0, 0, {0, 0, 0}, suppression_list, 0, 0},
234 {N_(
"units"), N_(
"Length units"),
235 HID_Enum, 0, 0, {0, 0, 0}, units_list, 0, 0},
237 {N_(
"digits"), N_(
"Number of digits. For trailing zero suppression,"
238 " this is the number of digits before the decimal point. "
239 "Otherwise this is the number of digits after the decimal point."),
240 HID_Integer, 0, 20, {5, 0, 0}, 0, 0, 0},
243 {
"tool_units",
"Tool size units",
244 HID_Enum, 0, 0, {0, 0, 0}, units_list, 0, 0},
249 drill_attribute_merge (gerbv_HID_Attribute *dest,
int ndest, gerbv_HID_Attribute *src,
int nsrc)
258 for (i = 0 ; i < nsrc ; i++) {
261 while (j < ndest && strcmp (src[i].name, dest[j].name) != 0)
265 if (j < ndest && src[i].type == dest[j].type) {
266 dest[j].default_val = src[i].default_val;
268 GERB_MESSAGE(
"Ignoring \"%s\" attribute for drill file", src[i].name);
277 info->min_x = MIN(info->min_x, bbox->
left);
278 info->min_y = MIN(info->min_y, bbox->
bottom);
279 info->max_x = MAX(info->max_x, bbox->
right);
280 info->max_y = MAX(info->max_y, bbox->
top);
287 drill_add_drill_hole (
gerbv_image_t *image, drill_state_t *state,
294 drill_stats_increment_drill_counter(image->
drill_stats->drill_list,
295 state->current_tool);
298 if (curr_net->
next == NULL) {
299 GERB_FATAL_ERROR(
"malloc curr_net->next failed in %s()",
303 curr_net = curr_net->
next;
306 curr_net->
start_x = state->curr_x;
307 curr_net->
start_y = state->curr_y;
320 curr_net->
aperture = state->current_tool;
325 if(image->
aperture[state->current_tool] == NULL) {
330 r = image->
aperture[state->current_tool]->parameter[0] / 2;
338 drill_update_image_info_min_max_from_bbox(image->
info, bbox);
349 drill_add_route_segment(
gerbv_image_t *image, drill_state_t *state,
350 gerbv_net_t *curr_net,
double prev_x,
double prev_y)
354 double start_x, start_y, stop_x, stop_y;
357 if (curr_net->
next == NULL) {
358 GERB_FATAL_ERROR(
"malloc curr_net->next failed in %s()",
362 curr_net = curr_net->
next;
368 stop_x = state->curr_x;
369 stop_y = state->curr_y;
382 curr_net->
stop_x = stop_x;
383 curr_net->
stop_y = stop_y;
384 curr_net->
aperture = state->current_tool;
390 if (image->
aperture[state->current_tool] == NULL) {
395 r = image->
aperture[state->current_tool]->parameter[0] / 2;
398 bbox->
left = MIN(start_x, stop_x) - r;
399 bbox->
right = MAX(start_x, stop_x) + r;
400 bbox->
bottom = MIN(start_y, stop_y) - r;
401 bbox->
top = MAX(start_y, stop_y) + r;
403 drill_update_image_info_min_max_from_bbox(image->
info, bbox);
412 drill_add_arc_segment(
gerbv_image_t *image, drill_state_t *state,
414 double prev_x,
double prev_y)
418 double start_x, start_y, stop_x, stop_y;
419 double delta_cp_x, delta_cp_y;
423 if (curr_net->
next == NULL)
424 GERB_FATAL_ERROR(
"malloc curr_net->next failed in %s()",
427 curr_net = curr_net->
next;
433 stop_x = state->curr_x;
434 stop_y = state->curr_y;
435 delta_cp_x = state->delta_cp_x;
436 delta_cp_y = state->delta_cp_y;
449 cw = (state->route_mode == DRILL_G_CWMOVE);
451 if (state->found_arc_radius) {
455 double radius = state->arc_radius;
456 double dx, dy, d, h, mx, my, px, py, sign, cp_x, cp_y;
461 dx = stop_x - start_x;
462 dy = stop_y - start_y;
465 if (d < DBL_EPSILON) {
469 delta_cp_y = fabs(radius);
470 }
else if (d > 2.0 * fabs(radius)) {
475 _(
"Arc radius %.4f too small for chord %.4f; "
476 "clamping to semicircle"),
478 delta_cp_x = dx / 2.0;
479 delta_cp_y = dy / 2.0;
481 h = sqrt(radius * radius - (d / 2.0) * (d / 2.0));
482 mx = (start_x + stop_x) / 2.0;
483 my = (start_y + stop_y) / 2.0;
491 sign = cw ? -1.0 : 1.0;
493 cp_x = mx + sign * h * px;
494 cp_y = my + sign * h * py;
496 delta_cp_x = cp_x - start_x;
497 delta_cp_y = cp_y - start_y;
500 state->found_arc_radius = FALSE;
505 curr_net->
stop_x = stop_x;
506 curr_net->
stop_y = stop_y;
507 curr_net->
aperture = state->current_tool;
513 curr_net->
cirseg = g_new0(gerbv_cirseg_t, 1);
514 if (curr_net->
cirseg == NULL)
515 GERB_FATAL_ERROR(
"malloc cirseg failed in %s()", __FUNCTION__);
517 calc_cirseg_mq(curr_net, cw, delta_cp_x, delta_cp_y);
520 if (image->
aperture[state->current_tool] == NULL)
525 r = image->
aperture[state->current_tool]->parameter[0] / 2;
528 double ang1, ang2, step_pi_2, x, y;
530 ang1 = DEG2RAD(MIN(curr_net->
cirseg->angle1,
531 curr_net->
cirseg->angle2));
532 ang2 = DEG2RAD(MAX(curr_net->
cirseg->angle1,
533 curr_net->
cirseg->angle2));
536 x = curr_net->
cirseg->cp_x +
537 curr_net->
cirseg->width * cos(ang1) / 2;
538 y = curr_net->
cirseg->cp_y +
539 curr_net->
cirseg->width * sin(ang1) / 2;
546 for (step_pi_2 = (floor(ang1 / M_PI_2) + 1) * M_PI_2;
547 step_pi_2 < MIN(ang2, ang1 + 2 * M_PI);
548 step_pi_2 += M_PI_2) {
549 x = curr_net->
cirseg->cp_x +
550 curr_net->
cirseg->width * cos(step_pi_2) / 2;
551 y = curr_net->
cirseg->cp_y +
552 curr_net->
cirseg->width * sin(step_pi_2) / 2;
553 bbox->
left = MIN(bbox->
left, x - r);
556 bbox->
top = MAX(bbox->
top, y + r);
560 x = curr_net->
cirseg->cp_x +
561 curr_net->
cirseg->width * cos(ang2) / 2;
562 y = curr_net->
cirseg->cp_y +
563 curr_net->
cirseg->width * sin(ang2) / 2;
564 bbox->
left = MIN(bbox->
left, x - r);
567 bbox->
top = MAX(bbox->
top, y + r);
570 drill_update_image_info_min_max_from_bbox(image->
info, bbox);
580 drill_add_circle_segment(
gerbv_image_t *image, drill_state_t *state,
582 double start_x,
double start_y,
583 double center_x,
double center_y, gboolean cw)
587 double cx, cy, sx, sy;
591 if (curr_net->
next == NULL)
592 GERB_FATAL_ERROR(
"malloc curr_net->next failed in %s()",
595 curr_net = curr_net->
next;
617 curr_net->
aperture = state->current_tool;
623 curr_net->
cirseg = g_new0(gerbv_cirseg_t, 1);
624 if (curr_net->
cirseg == NULL)
625 GERB_FATAL_ERROR(
"malloc cirseg failed in %s()", __FUNCTION__);
627 r = hypot(sx - cx, sy - cy);
628 curr_net->
cirseg->cp_x = cx;
629 curr_net->
cirseg->cp_y = cy;
630 curr_net->
cirseg->width = r * 2.0;
631 curr_net->
cirseg->height = r * 2.0;
634 start_angle = RAD2DEG(atan2(sy - cy, sx - cx));
636 start_angle += 360.0;
639 curr_net->
cirseg->angle1 = start_angle;
640 curr_net->
cirseg->angle2 = start_angle - 360.0;
642 curr_net->
cirseg->angle1 = start_angle;
643 curr_net->
cirseg->angle2 = start_angle + 360.0;
647 if (image->
aperture[state->current_tool] == NULL)
651 tool_r = image->
aperture[state->current_tool]->parameter[0] / 2;
653 bbox->
left = cx - r - tool_r;
654 bbox->
right = cx + r + tool_r;
655 bbox->
bottom = cy - r - tool_r;
656 bbox->
top = cy + r + tool_r;
658 drill_update_image_info_min_max_from_bbox(image->
info, bbox);
665 parse_drillfile(gerb_file_t *fd, gerbv_HID_Attribute *attr_list,
int n_attr,
int reload)
667 drill_state_t *state = NULL;
670 gerbv_HID_Attribute *hid_attrs;
672 gboolean parsing_done = FALSE;
675 unsigned int file_line = 1;
682 setlocale(LC_NUMERIC,
"C" );
685 DPRINTF(
"In parse_drillfile, about to create image for this layer\n");
689 GERB_FATAL_ERROR(
"malloc image failed in %s()", __FUNCTION__);
692 if (reload && attr_list != NULL) {
696 image->
info->n_attr = n_attr;
697 image->
info->attr_list = gerbv_attribute_dup(attr_list, n_attr);
704 image->
info->n_attr =
sizeof (drill_attribute_list) /
sizeof (drill_attribute_list[0]);
705 image->
info->attr_list = gerbv_attribute_dup (drill_attribute_list, image->
info->n_attr);
708 drill_attribute_merge (image->
info->attr_list, image->
info->n_attr,
718 GERB_FATAL_ERROR(
"malloc stats failed in %s()", __FUNCTION__);
725 GERB_FATAL_ERROR(
"malloc state failed in %s()", __FUNCTION__);
729 if (image->
format == NULL) {
730 GERB_FATAL_ERROR(
"malloc format failed in %s()", __FUNCTION__);
735 hid_attrs = image->
info->attr_list;
737 if (!hid_attrs[HA_auto].default_val.int_value) {
739 state->number_format = FMT_USER;
740 state->decimals = hid_attrs[HA_digits].default_val.int_value;
742 if (
GERBV_UNIT_MM == hid_attrs[HA_xy_units].default_val.int_value) {
746 switch (hid_attrs[HA_suppression].default_val.int_value) {
761 DPRINTF(
"%s(): Starting parsing of drill file \"%s\"\n",
762 __FUNCTION__, fd->filename);
764 while (!parsing_done && (read = gerb_fgetc(fd)) != EOF) {
766 switch ((
char) read) {
770 if (drill_parse_header_is_metric_comment(fd, state, image, file_line)) {
775 _(
"Comment \"%s\" at line %u in file \"%s\""),
776 tmps, file_line, fd->filename);
777 DPRINTF(
" Comment with ';' \"%s\" at line %u\n",
788 if (strcmp(tmps,
"ATC,ON") == 0 ||
789 strcmp(tmps,
"ATC,OFF") == 0) {
791 _(
"Ignoring ATC command \"%s\" "
792 "at line %u in file \"%s\""),
793 tmps, file_line, fd->filename);
796 _(
"Undefined code \"%s\" "
797 "at line %u in file \"%s\""),
798 tmps, file_line, fd->filename);
805 tmps = get_line (fd);
806 if (strcmp (tmps,
"DETECT,ON") == 0 ||
807 strcmp (tmps,
"DETECT,OFF") == 0) {
810 if (strcmp (tmps,
"DETECT,ON") == 0) {
818 tmps2 = g_strdup_printf (
"%s\n%s", stats->detect, tmps3);
819 g_free (stats->detect);
821 tmps2 = g_strdup_printf (
"%s", tmps3);
823 stats->detect = tmps2;
826 _(
"Unrecognised string \"%s\" in header "
827 "at line %u in file \"%s\""),
828 tmps, file_line, fd->filename);
835 tmps = get_line (fd);
838 if (0 == strcmp (tmps,
"FMAT,2")) {
843 if (0 == strcmp (tmps,
"FMAT,1")) {
844 gerbv_stats_printf(stats->error_list,
846 _(
"File in unsupported format 1 "
847 "at line %u in file \"%s\""),
848 file_line, fd->filename);
856 gerbv_stats_printf(stats->error_list,
858 _(
"Unrecognised string \"%s\" in header "
859 "at line %u in file \"%s\""),
860 tmps, file_line, fd->filename);
867 drill_g_code_t g_code;
869 switch (g_code = drill_parse_G_code(fd, image, file_line)) {
873 state->route_mode = DRILL_G_DRILL;
874 state->tool_down = FALSE;
878 state->route_mode = DRILL_G_ROUT;
880 case DRILL_G_LINEARMOVE :
881 state->route_mode = DRILL_G_LINEARMOVE;
883 case DRILL_G_CWMOVE :
884 state->route_mode = DRILL_G_CWMOVE;
886 case DRILL_G_CCWMOVE :
887 state->route_mode = DRILL_G_CCWMOVE;
890 case DRILL_G_SLOT : {
895 if (EOF == (read = gerb_fgetc(fd))) {
896 gerbv_stats_printf(stats->error_list,
898 _(
"Unexpected EOF found in file \"%s\""),
903 drill_parse_coordinate(fd, read, image, state, file_line);
906 curr_net->
stop_x = state->curr_x;
907 curr_net->
stop_y = state->curr_y;
915 r = image->
aperture[state->current_tool]->parameter[0]/2;
923 drill_update_image_info_min_max_from_bbox(image->
info, bbox);
930 case DRILL_G_ROUTSLOT : {
933 double prev_x = state->curr_x;
934 double prev_y = state->curr_y;
936 if (EOF == (read = gerb_fgetc(fd))) {
937 gerbv_stats_printf(stats->error_list,
939 _(
"Unexpected EOF found in file \"%s\""),
944 drill_parse_coordinate(fd, read, image, state, file_line);
946 curr_net = drill_add_route_segment(image, state, curr_net,
951 case DRILL_G_ROUTCIRCLE:
952 case DRILL_G_ROUTCIRCLECCW: {
953 double circ_start_x = state->curr_x;
954 double circ_start_y = state->curr_y;
956 if (EOF == (read = gerb_fgetc(fd))) {
957 gerbv_stats_printf(stats->error_list,
959 _(
"Unexpected EOF found in file \"%s\""),
965 drill_parse_coordinate(fd, read, image, state, file_line);
968 curr_net = drill_add_circle_segment(image, state, stats,
969 curr_net, circ_start_x, circ_start_y,
970 state->curr_x, state->curr_y,
971 g_code == DRILL_G_ROUTCIRCLE);
974 state->curr_x = circ_start_x;
975 state->curr_y = circ_start_y;
980 case DRILL_G_ABSOLUTE :
981 state->coordinate_mode = DRILL_MODE_ABSOLUTE;
984 case DRILL_G_INCREMENTAL :
985 state->coordinate_mode = DRILL_MODE_INCREMENTAL;
988 case DRILL_G_ZEROSET :
989 if (EOF == (read = gerb_fgetc(fd))) {
990 gerbv_stats_printf(stats->error_list,
992 _(
"Unexpected EOF found in file \"%s\""),
997 drill_parse_coordinate(fd, (
char)read, image,
999 state->origin_x = state->curr_x;
1000 state->origin_y = state->curr_y;
1003 case DRILL_G_UNKNOWN:
1004 tmps = get_line(fd);
1005 gerbv_stats_printf(stats->error_list,
1007 _(
"Unrecognized string \"%s\" found "
1008 "at line %u in file \"%s\""),
1009 tmps, file_line, fd->filename);
1013 case DRILL_G_OVERRIDETOOLSPEED:
1014 case DRILL_G_VISTOOL:
1015 case DRILL_G_VISSINGLEPOINTOFFSET:
1016 case DRILL_G_VISMULTIPOINTTRANS:
1017 case DRILL_G_VISCANCEL:
1018 case DRILL_G_VISCORRHOLEDRILL:
1019 case DRILL_G_VISAUTOCALIBRATION:
1020 case DRILL_G_CUTTERCOMPOFF:
1021 case DRILL_G_CUTTERCOMPLEFT:
1022 case DRILL_G_CUTTERCOMPRIGHT:
1023 case DRILL_G_VISSINGLEPOINTOFFSETREL:
1024 case DRILL_G_VISMULTIPOINTTRANSREL:
1025 case DRILL_G_VISCANCELREL:
1026 case DRILL_G_VISCORRHOLEDRILLREL:
1027 case DRILL_G_PACKDIP2:
1028 case DRILL_G_PACKDIP:
1029 case DRILL_G_PACK8PINL:
1032 gerbv_stats_printf(stats->error_list,
1034 _(
"Ignoring machine-only G%02d (%s) "
1035 "at line %u in file \"%s\""),
1037 file_line, fd->filename);
1043 _(
"Unsupported G%02d (%s) code "
1044 "at line %u in file \"%s\""),
1046 file_line, fd->filename);
1056 if (drill_parse_header_is_inch(fd, state, image, file_line)) {
1060 if (drill_parse_header_is_ici(fd, state, image, file_line)) {
1064 tmps = get_line(fd);
1065 gerbv_stats_printf(stats->error_list,
1067 _(
"Unrecognized string \"%s\" found "
1068 "at line %u in file \"%s\""),
1069 tmps, file_line, fd->filename);
1077 switch (m_code = drill_parse_M_code(fd, state, image, file_line)) {
1078 case DRILL_M_HEADER :
1079 state->curr_section = DRILL_HEADER;
1081 case DRILL_M_HEADEREND :
1082 state->curr_section = DRILL_DATA;
1093 gerbv_stats_printf(stats->error_list,
1095 _(
"End of Excellon header reached "
1096 "but no leading/trailing zero "
1097 "handling specified "
1098 "at line %u in file \"%s\""),
1099 file_line, fd->filename);
1100 gerbv_stats_printf(stats->error_list,
1102 _(
"Assuming leading zeros in file \"%s\""),
1107 case DRILL_M_METRIC :
1109 && state->curr_section != DRILL_HEADER) {
1112 gerbv_stats_printf(stats->error_list,
1114 _(
"M71 code found but no METRIC "
1115 "specification in header "
1116 "at line %u in file \"%s\""),
1117 file_line, fd->filename);
1118 gerbv_stats_printf(stats->error_list,
1120 _(
"Assuming all tool sizes are MM in file \"%s\""),
1124 for (
int tool_num = TOOL_MIN; tool_num < TOOL_MAX;
1129 size = image->
aperture[tool_num]->parameter[0];
1130 drill_stats_modify_drill_list(stats->drill_list,
1137 image->
aperture[tool_num]->parameter[0] /= 25.4;
1142 state->number_format = state->backup_number_format;
1146 case DRILL_M_IMPERIAL :
1148 if (state->number_format != FMT_00_0000) {
1150 state->backup_number_format = state->number_format;
1152 state->number_format = FMT_00_0000;
1153 state->decimals = 4;
1158 case DRILL_M_CANNEDTEXTX :
1159 case DRILL_M_CANNEDTEXTY :
1160 tmps = get_line(fd);
1162 _(
"Canned text \"%s\" "
1163 "at line %u in drill file \"%s\""),
1164 tmps, file_line, fd->filename);
1167 case DRILL_M_MESSAGELONG :
1168 case DRILL_M_MESSAGE :
1169 tmps = get_line(fd);
1171 _(
"Message \"%s\" embedded "
1172 "at line %u in drill file \"%s\""),
1173 tmps, file_line, fd->filename);
1176 case DRILL_M_PATTERN:
1177 state->in_pattern = TRUE;
1178 if (state->pattern_buffer) {
1179 g_array_set_size(state->pattern_buffer, 0);
1181 state->pattern_buffer = g_array_new(FALSE, FALSE,
1182 sizeof(drill_pattern_entry_t));
1186 case DRILL_M_PATTERNEND:
1187 state->in_pattern = FALSE;
1190 case DRILL_M_REPEATPATTERNOFFSET: {
1191 double offset_x = 0.0, offset_y = 0.0;
1197 offset_x = read_double(fd, state->number_format,
1198 image->
format->omit_zeros, state->decimals);
1202 offset_y = read_double(fd, state->number_format,
1203 image->
format->omit_zeros, state->decimals);
1209 if (state->pattern_buffer && state->pattern_buffer->len > 0) {
1210 double save_x = state->curr_x;
1211 double save_y = state->curr_y;
1212 saved_tool = state->current_tool;
1214 for (guint i = 0; i < state->pattern_buffer->len; i++) {
1215 drill_pattern_entry_t *e = &g_array_index(
1216 state->pattern_buffer,
1217 drill_pattern_entry_t, i);
1218 state->current_tool = e->tool;
1219 state->curr_x = e->x + offset_x;
1220 state->curr_y = e->y + offset_y;
1223 curr_net = drill_add_route_segment(image, state,
1225 e->prev_x + offset_x,
1226 e->prev_y + offset_y);
1228 curr_net = drill_add_drill_hole(image, state,
1233 state->curr_x = save_x;
1234 state->curr_y = save_y;
1235 state->current_tool = saved_tool;
1240 case DRILL_M_TOOLTIPCHECK:
1243 case DRILL_M_ZAXISROUTEPOSITIONDEPTHCTRL:
1244 case DRILL_M_ZAXISROUTEPOSITION:
1245 state->tool_down = TRUE;
1247 case DRILL_M_RETRACTCLAMPING:
1248 case DRILL_M_RETRACTNOCLAMPING:
1249 state->tool_down = FALSE;
1252 case DRILL_M_SWAPAXIS:
1253 state->swap_axis = !state->swap_axis;
1255 case DRILL_M_MIRRORX:
1256 state->mirror_x = !state->mirror_x;
1258 case DRILL_M_MIRRORY:
1259 state->mirror_y = !state->mirror_y;
1268 case DRILL_M_ENDREWIND :
1269 parsing_done = TRUE;
1272 case DRILL_M_UNKNOWN:
1275 if (drill_parse_header_is_metric(fd, state, image, file_line)) {
1280 tmps = get_line(fd);
1281 gerbv_stats_printf(stats->error_list,
1283 _(
"Unrecognized string \"%s\" found "
1284 "at line %u in file \"%s\""),
1285 tmps, file_line, fd->filename);
1290 case DRILL_M_STOPOPTIONAL:
1291 case DRILL_M_SANDREND:
1292 case DRILL_M_STOPINSPECTION:
1293 case DRILL_M_VISANDRPATTERN:
1294 case DRILL_M_VISANDRPATTERNREWIND:
1295 case DRILL_M_VISANDRPATTERNOFFSETCOUNTERCTRL:
1296 case DRILL_M_REFSCALING:
1297 case DRILL_M_REFSCALINGEND:
1298 case DRILL_M_PECKDRILLING:
1299 case DRILL_M_PECKDRILLINGEND:
1301 gerbv_stats_printf(stats->error_list,
1303 _(
"Ignoring machine-only M%02d (%s) "
1304 "at line %u in file \"%s\""),
1306 file_line, fd->filename);
1312 _(
"Unsupported M%02d (%s) code found "
1313 "at line %u in file \"%s\""),
1315 file_line, fd->filename);
1323 if (state->curr_section == DRILL_HEADER) {
1326 _(
"Not allowed 'R' code in the header "
1327 "at line %u in file \"%s\""),
1328 file_line, fd->filename);
1330 double start_x, start_y;
1331 double step_x, step_y;
1347 start_x = state->curr_x;
1348 start_y = state->curr_y;
1351 c = gerb_fgetc (fd);
1353 while (
'0' <= c && c <=
'9') {
1354 rcnt = 10*rcnt + (c -
'0');
1355 c = gerb_fgetc (fd);
1357 DPRINTF(
"working on R code (repeat) with a number of reps equal to %d\n", rcnt);
1361 step_x = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
1362 c = gerb_fgetc (fd);
1367 step_y = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
1372 DPRINTF(
"Getting ready to repeat the drill %d times with delta_x = %g, delta_y = %g\n", rcnt, step_x, step_y);
1375 for (c = 1 ; c <= rcnt ; c++) {
1376 state->curr_x = start_x + c*step_x;
1377 state->curr_y = start_y + c*step_y;
1378 DPRINTF(
" Repeat #%d - new location is (%g, %g)\n", c, state->curr_x, state->curr_y);
1379 curr_net = drill_add_drill_hole (image, state, curr_net);
1380 if (state->in_pattern) {
1381 drill_pattern_entry_t entry = {
1382 state->curr_x, state->curr_y,
1383 0, 0, state->current_tool, FALSE
1385 g_array_append_val(state->pattern_buffer, entry);
1394 _(
"Ignoring setting spindle speed "
1395 "at line %u in drill file \"%s\""),
1396 file_line, fd->filename);
1400 drill_parse_T_code(fd, state, image, file_line);
1401 state->route_mode = DRILL_G_DRILL;
1402 state->tool_down = FALSE;
1403 state->delta_cp_x = 0;
1404 state->delta_cp_y = 0;
1408 tmps = get_line (fd);
1410 if (0 != strcmp (tmps,
"VER,1")) {
1412 _(
"Undefined string \"%s\" in header "
1413 "at line %u in file \"%s\""),
1414 tmps, file_line, fd->filename);
1421 double prev_x = state->curr_x;
1422 double prev_y = state->curr_y;
1425 drill_parse_coordinate(fd, read, image, state, file_line);
1427 if ((state->route_mode == DRILL_G_ROUT ||
1428 state->route_mode == DRILL_G_LINEARMOVE ||
1429 state->route_mode == DRILL_G_CWMOVE ||
1430 state->route_mode == DRILL_G_CCWMOVE) && !state->tool_down) {
1432 state->delta_cp_x = 0;
1433 state->delta_cp_y = 0;
1434 state->found_arc_radius = FALSE;
1438 if ((state->route_mode == DRILL_G_CWMOVE ||
1439 state->route_mode == DRILL_G_CCWMOVE) && state->tool_down) {
1441 curr_net = drill_add_arc_segment(image, state, stats,
1442 curr_net, prev_x, prev_y);
1443 state->delta_cp_x = 0;
1444 state->delta_cp_y = 0;
1445 state->found_arc_radius = FALSE;
1446 }
else if ((state->route_mode == DRILL_G_LINEARMOVE ||
1447 state->route_mode == DRILL_G_ROUT) && state->tool_down) {
1449 curr_net = drill_add_route_segment(image, state,
1450 curr_net, prev_x, prev_y);
1451 if (state->in_pattern) {
1452 drill_pattern_entry_t entry = {
1453 state->curr_x, state->curr_y,
1454 prev_x, prev_y, state->current_tool, TRUE
1456 g_array_append_val(state->pattern_buffer, entry);
1460 curr_net = drill_add_drill_hole(image, state, curr_net);
1461 if (state->in_pattern) {
1462 drill_pattern_entry_t entry = {
1463 state->curr_x, state->curr_y,
1464 0, 0, state->current_tool, FALSE
1466 g_array_append_val(state->pattern_buffer, entry);
1473 state->curr_section = DRILL_DATA;
1480 read = gerb_fgetc(fd);
1481 if (read !=
'\r' && read != EOF) {
1490 read = gerb_fgetc(fd);
1491 if (read !=
'\n' && read != EOF) {
1503 if (DRILL_HEADER == state->curr_section) {
1505 _(
"Undefined code '%s' (0x%x) found in header "
1506 "at line %u in file \"%s\""),
1507 gerbv_escape_char(read), read,
1508 file_line, fd->filename);
1512 tmps = get_line(fd);
1514 _(
"Unrecognised string \"%s\" in header "
1515 "at line %u in file \"%s\""),
1516 tmps, file_line, fd->filename);
1520 _(
"Ignoring undefined character '%s' (0x%x) "
1521 "found inside data at line %u in file \"%s\""),
1522 gerbv_escape_char(read), read, file_line, fd->filename);
1527 if (!parsing_done) {
1529 _(
"No EOF found in drill file \"%s\""), fd->filename);
1532 DPRINTF(
"%s(): Populating file attributes\n", __FUNCTION__);
1534 hid_attrs = image->
info->attr_list;
1536 switch (state->unit) {
1538 hid_attrs[HA_xy_units].default_val.int_value =
GERBV_UNIT_MM;
1546 switch (state->number_format) {
1549 hid_attrs[HA_digits].default_val.int_value = 2;
1553 hid_attrs[HA_digits].default_val.int_value = 3;
1557 hid_attrs[HA_digits].default_val.int_value = 4;
1561 DPRINTF(
"%s(): Keeping user specified number of decimal places (%d)\n",
1563 hid_attrs[HA_digits].default_val.int_value);
1570 switch (image->
format->omit_zeros) {
1572 hid_attrs[HA_suppression].default_val.int_value = SUP_LEAD;
1576 hid_attrs[HA_suppression].default_val.int_value = SUP_TRAIL;
1580 hid_attrs[HA_suppression].default_val.int_value = SUP_NONE;
1584 if (state->pattern_buffer)
1585 g_array_free(state->pattern_buffer, TRUE);
1598 drill_file_p(gerb_file_t *fd, gboolean *returnFoundBinary)
1600 char *buf=NULL, *tbuf;
1607 gboolean found_binary = FALSE;
1608 gboolean found_M48 = FALSE;
1609 gboolean found_M30 = FALSE;
1610 gboolean found_percent = FALSE;
1611 gboolean found_T = FALSE;
1612 gboolean found_X = FALSE;
1613 gboolean found_Y = FALSE;
1614 gboolean end_comments=FALSE;
1616 tbuf = g_malloc(MAXL);
1619 "malloc buf failed while checking for drill file in %s()",
1623 while (fgets(tbuf, MAXL, fd->fd) != NULL) {
1628 if(g_strstr_len(buf, len,
";")!=NULL){
1629 for (i = 0; i < len-1; ++i) {
1633 && buf[i+1] !=
'\n') {
1634 end_comments = TRUE;
1652 for (i = 0; i < len; i++) {
1653 ascii = (int) buf[i];
1654 if ((ascii > 128) || (ascii < 0)) {
1655 found_binary = TRUE;
1660 if (g_strstr_len(buf, len,
"M48")) {
1665 if (g_strstr_len(buf, len,
"M30")) {
1666 if (found_percent) {
1672 if ((letter = g_strstr_len(buf, len,
"%")) != NULL) {
1673 if ((letter[1] ==
'\r') || (letter[1] ==
'\n')) {
1674 found_percent = TRUE;
1679 if ((letter = g_strstr_len(buf, len,
"T")) != NULL) {
1680 if (!found_T && (found_X || found_Y)) {
1683 if (isdigit( (
int) letter[1])) {
1690 if ((letter = g_strstr_len(buf, len,
"X")) != NULL) {
1691 ascii = (int) letter[1];
1692 if ((ascii >= zero) && (ascii <= nine)) {
1696 if ((letter = g_strstr_len(buf, len,
"Y")) != NULL) {
1697 ascii = (int) letter[1];
1698 if ((ascii >= zero) && (ascii <= nine)) {
1706 *returnFoundBinary = found_binary;
1709 if ( ((found_X || found_Y) && found_T) &&
1710 (found_M48 || (found_percent && found_M30)) ) {
1712 }
else if (found_M48 && found_percent && found_M30) {
1727 drill_parse_T_code(gerb_file_t *fd, drill_state_t *state,
1731 gboolean done = FALSE;
1735 gerbv_aperture_t *apert;
1739 DPRINTF(
"---> entering %s()...\n", __FUNCTION__);
1743 temp = gerb_fgetc(fd);
1744 DPRINTF(
" Found a char '%s' (0x%02x) after the T\n",
1745 gerbv_escape_char(temp), temp);
1748 if((temp ==
'C') && ((fd->ptr + 2) < fd->datalen)){
1749 if(gerb_fgetc(fd) ==
'S'){
1750 if (gerb_fgetc(fd) ==
'T' ){
1752 tmps = get_line(fd++);
1754 _(
"Tool change stop switch found \"%s\" "
1755 "at line %u in file \"%s\""),
1756 tmps, file_line, fd->filename);
1766 if( !(isdigit(temp) != 0 || temp ==
'+' || temp ==
'-') ) {
1769 _(
"OrCAD bug: Junk text found in place of tool definition"));
1770 tmps = get_line(fd);
1772 _(
"Junk text \"%s\" "
1773 "at line %u in file \"%s\""),
1774 tmps, file_line, fd->filename);
1777 _(
"Ignoring junk text"));
1783 tool_num = (int) gerb_fgetint(fd, NULL);
1784 DPRINTF(
" Handling tool T%d at line %u\n", tool_num, file_line);
1786 if (tool_num == 0) {
1791 temp = gerb_fgetc(fd);
1792 while (temp != EOF && temp !=
'\n' && temp !=
'\r') {
1794 read_double(fd, state->header_number_format,
1796 }
else if (temp ==
'F' || temp ==
'S') {
1797 gerb_fgetint(fd, NULL);
1802 temp = gerb_fgetc(fd);
1804 if (temp ==
'\n' || temp ==
'\r')
1809 if (tool_num < TOOL_MIN || tool_num >= TOOL_MAX) {
1811 _(
"Out of bounds drill number %d "
1812 "at line %u in file \"%s\""),
1813 tool_num, file_line, fd->filename);
1818 state->current_tool = tool_num;
1822 temp = gerb_fgetc(fd);
1827 switch((
char)temp) {
1830 DPRINTF(
" Read a size of %g\n", size);
1834 }
else if(size >= 4.0) {
1842 _(
"Read a drill of diameter %g inches "
1843 "at line %u in file \"%s\""),
1844 size, file_line, fd->filename);
1846 _(
"Assuming units are mils"));
1850 if (size <= 0. || size >= 10000.) {
1852 _(
"Unreasonable drill size %g found for drill %d "
1853 "at line %u in file \"%s\""),
1854 size, tool_num, file_line, fd->filename);
1856 if (apert != NULL) {
1861 if (apert->parameter[0] != size
1863 || apert->nuf_parameters != 1
1866 gerbv_stats_printf(stats->error_list,
1868 _(
"Found redefinition of drill %d "
1869 "at line %u in file \"%s\""),
1870 tool_num, file_line, fd->filename);
1873 apert = image->
aperture[tool_num] =
1874 g_new0(gerbv_aperture_t, 1);
1875 if (apert == NULL) {
1876 GERB_FATAL_ERROR(
"malloc tool failed in %s()",
1883 apert->parameter[0] = size;
1885 apert->nuf_parameters = 1;
1893 string = g_strdup_printf(
"%s", (state->unit ==
GERBV_UNIT_MM ? _(
"mm") : _(
"inch")));
1894 drill_stats_add_to_drill_list(stats->drill_list,
1904 gerb_fgetint(fd, NULL);
1915 temp = gerb_fgetc(fd);
1918 _(
"Unexpected EOF encountered in header of "
1919 "drill file \"%s\""), fd->filename);
1922 if (
'\n' == temp ||
'\r' == temp) {
1930 if (apert == NULL) {
1933 apert = image->
aperture[tool_num] = g_new0(gerbv_aperture_t, 1);
1934 if (apert == NULL) {
1935 GERB_FATAL_ERROR(
"malloc tool failed in %s()", __FUNCTION__);
1939 dia = gerbv_get_tool_diameter(tool_num);
1945 dia = (double)(16 + 8 * tool_num) / 1000;
1951 if (tool_num != 0) {
1953 _(
"Tool %02d used without being defined "
1954 "at line %u in file \"%s\""),
1955 tool_num, file_line, fd->filename);
1957 _(
"Setting a default size of %g\""), dia);
1962 apert->nuf_parameters = 1;
1963 apert->parameter[0] = dia;
1967 if (tool_num != 0) {
1970 string = g_strdup_printf(
"%s",
1972 drill_stats_add_to_drill_list(stats->drill_list,
1980 DPRINTF(
"<---- ...leaving %s()\n", __FUNCTION__);
1987 static drill_m_code_t
1988 drill_parse_M_code(gerb_file_t *fd, drill_state_t *state,
1992 drill_m_code_t m_code;
1995 DPRINTF(
"---> entering %s() ...\n", __FUNCTION__);
1997 op[0] = gerb_fgetc(fd);
1998 op[1] = gerb_fgetc(fd);
2004 _(
"Unexpected EOF found while parsing M-code in file \"%s\""),
2007 return DRILL_M_UNKNOWN;
2010 DPRINTF(
" Compare M-code \"%s\" at line %u\n", op, file_line);
2012 switch (m_code = atoi(op)) {
2015 if (0 != strncmp(op,
"00", 2)) {
2016 m_code = DRILL_M_UNKNOWN;
2080 case 50:
case 51:
case 52:
2081 case 60:
case 61:
case 62:
case 63:
2082 stats->M_machine_only++;
2086 case DRILL_M_UNKNOWN:
2091 DPRINTF(
"<---- ...leaving %s()\n", __FUNCTION__);
2098 drill_parse_header_is_metric(gerb_file_t *fd, drill_state_t *state,
2104 DPRINTF(
" %s(): entering\n", __FUNCTION__);
2113 if (DRILL_HEADER != state->curr_section) {
2117 switch (file_check_str(fd,
"METRIC")) {
2120 _(
"Unexpected EOF found while parsing \"%s\" string "
2121 "in file \"%s\""),
"METRIC", fd->filename);
2129 gboolean found_junk = FALSE;
2131 if (
',' != gerb_fgetc(fd)) {
2138 switch (c = gerb_fgetc(fd)) {
2141 if (
'Z' != gerb_fgetc(fd)) {
2147 DPRINTF(
" %s(): Detected a file that probably has "
2148 "trailing zero suppression\n", __FUNCTION__);
2151 DPRINTF(
" %s(): Detected a file that probably has "
2152 "leading zero suppression\n", __FUNCTION__);
2156 if (!state->autod && state->number_format == FMT_USER
2157 && state->digits_before > 0 && c ==
'L') {
2160 state->decimals = state->digits_before;
2165 state->header_number_format = FMT_000_000;
2167 if (state->autod && state->number_format != FMT_USER) {
2174 state->number_format = FMT_000_000;
2175 state->decimals = 3;
2178 if (
',' == gerb_fgetc(fd)) {
2187 if (
'0' != gerb_fgetc(fd)
2188 ||
'0' != gerb_fgetc(fd)) {
2195 op[0] = gerb_fgetc(fd);
2196 op[1] = gerb_fgetc(fd);
2204 if (0 == strcmp(op,
"0.")) {
2207 if (
'0' != gerb_fgetc(fd)
2208 ||
'0' != gerb_fgetc(fd)) {
2216 state->number_format = FMT_0000_00;
2217 state->decimals = 2;
2222 if (0 != strcmp(op,
".0")) {
2229 if (
'0' != gerb_fgetc(fd)) {
2238 int last_char = gerb_fgetc(fd);
2239 if (last_char ==
'0') {
2241 state->number_format = FMT_000_000;
2242 state->decimals = 3;
2245 if (last_char != EOF) {
2249 state->number_format = FMT_000_00;
2250 state->decimals = 2;
2267 gerbv_stats_printf(stats->error_list,
2269 _(
"Found junk after METRIC command "
2270 "at line %u in file \"%s\""),
2271 file_line, fd->filename);
2290 drill_parse_header_is_metric_comment(gerb_file_t *fd, drill_state_t *state,
2294 DPRINTF(
" %s(): entering\n", __FUNCTION__);
2296 if (DRILL_HEADER != state->curr_section) {
2300 switch (file_check_str(fd,
"FILE_FORMAT")) {
2303 _(
"Unexpected EOF found while parsing \"%s\" string "
2304 "in file \"%s\" on line %u"),
2305 "FILE_FORMAT", fd->filename, file_line);
2312 if (file_check_str(fd,
"=") != 1) {
2314 _(
"Expected '=' while parsing \"%s\" string "
2315 "in file \"%s\" on line %u"),
2316 "FILE_FORMAT", fd->filename, file_line);
2321 int digits_before = gerb_fgetint(fd, &len);
2326 _(
"Expected integer after '=' while parsing \"%s\" string "
2327 "in file \"%s\" on line %u"),
2328 "FILE_FORMAT", fd->filename, file_line);
2332 if (file_check_str(fd,
":") != 1) {
2334 _(
"Expected ':' while parsing \"%s\" string "
2335 "in file \"%s\" on line %u"),
2336 "FILE_FORMAT", fd->filename, file_line);
2341 int digits_after = gerb_fgetint(fd, &len);
2345 _(
"Expected integer after ':' while parsing \"%s\" string "
2346 "in file \"%s\" on line %u"),
2347 "FILE_FORMAT", fd->filename, file_line);
2351 state->number_format = FMT_USER;
2355 state->decimals = digits_after;
2356 state->digits_before = digits_before;
2363 drill_parse_header_is_inch(gerb_file_t *fd, drill_state_t *state,
2369 DPRINTF(
" %s(): entering\n", __FUNCTION__);
2371 if (DRILL_HEADER != state->curr_section) {
2375 switch (file_check_str(fd,
"INCH")) {
2378 _(
"Unexpected EOF found while parsing \"%s\" string "
2379 "in file \"%s\""),
"INCH", fd->filename);
2387 if (
',' != gerb_fgetc(fd)) {
2392 if (c != EOF &&
'Z' == gerb_fgetc(fd)) {
2396 state->header_number_format = FMT_00_0000;
2398 state->number_format = FMT_00_0000;
2399 state->decimals = 4;
2400 }
else if (state->number_format == FMT_USER
2401 && state->digits_before > 0) {
2404 state->decimals = state->digits_before;
2410 state->header_number_format = FMT_00_0000;
2412 state->number_format = FMT_00_0000;
2413 state->decimals = 4;
2420 gerbv_stats_printf(stats->error_list,
2422 _(
"Found junk '%s' after "
2424 "at line %u in file \"%s\""),
2425 gerbv_escape_char(c),
2426 file_line, fd->filename);
2430 gerbv_stats_printf(stats->error_list,
2432 _(
"Found junk '%s' after INCH command "
2433 "at line %u in file \"%s\""),
2434 gerbv_escape_char(c),
2435 file_line, fd->filename);
2449 drill_parse_header_is_ici(gerb_file_t *fd, drill_state_t *state,
2454 switch (file_check_str(fd,
"ICI,ON")) {
2457 _(
"Unexpected EOF found while parsing \"%s\" string "
2458 "in file \"%s\""),
"ICI,ON", fd->filename);
2462 state->coordinate_mode = DRILL_MODE_INCREMENTAL;
2466 switch (file_check_str(fd,
"ICI,OFF")) {
2469 _(
"Unexpected EOF found while parsing \"%s\" string "
2470 "in file \"%s\""),
"ICI,OFF", fd->filename);
2474 state->coordinate_mode = DRILL_MODE_ABSOLUTE;
2482 static drill_g_code_t
2483 drill_parse_G_code(gerb_file_t *fd,
gerbv_image_t *image,
unsigned int file_line)
2486 drill_g_code_t g_code;
2489 DPRINTF(
"---> entering %s()...\n", __FUNCTION__);
2491 op[0] = gerb_fgetc(fd);
2492 op[1] = gerb_fgetc(fd);
2498 _(
"Unexpected EOF found while parsing G-code in file \"%s\""),
2500 return DRILL_G_UNKNOWN;
2503 DPRINTF(
" Compare G-code \"%s\" at line %u\n", op, file_line);
2505 switch (g_code = atoi(op)) {
2508 if (0 != strncmp(op,
"00", 2)) {
2509 g_code = DRILL_G_UNKNOWN;
2551 case 34:
case 35:
case 36:
case 37:
case 38:
case 39:
2552 case 40:
case 41:
case 42:
2553 case 45:
case 46:
case 47:
case 48:
2554 case 81:
case 82:
case 83:
case 84:
2555 stats->G_machine_only++;
2558 case DRILL_G_UNKNOWN:
2564 DPRINTF(
"<---- ...leaving %s()\n", __FUNCTION__);
2574 drill_parse_coordinate(gerb_file_t *fd,
char firstchar,
2576 unsigned int file_line)
2581 gboolean found_x = FALSE;
2583 gboolean found_y = FALSE;
2585 gboolean found_i = FALSE;
2587 gboolean found_j = FALSE;
2591 if (firstchar ==
'X') {
2592 x = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
2594 }
else if (firstchar ==
'Y') {
2595 y = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
2597 }
else if (firstchar ==
'I') {
2598 i_val = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
2600 }
else if (firstchar ==
'J') {
2601 j_val = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
2603 }
else if (firstchar ==
'A') {
2604 state->arc_radius = read_double(fd, state->number_format,
2605 image->
format->omit_zeros, state->decimals);
2606 state->found_arc_radius = TRUE;
2612 firstchar = gerb_fgetc(fd);
2615 if (state->swap_axis) {
2616 double tmp = x; x = y; y = tmp;
2617 gboolean ftmp = found_x; found_x = found_y; found_y = ftmp;
2619 if (state->mirror_x && found_x)
2621 if (state->mirror_y && found_y)
2624 if(state->coordinate_mode == DRILL_MODE_ABSOLUTE) {
2631 }
else if(state->coordinate_mode == DRILL_MODE_INCREMENTAL) {
2640 _(
"Coordinate mode is not absolute and not incremental "
2641 "at line %u in file \"%s\""),
2642 file_line, fd->filename);
2647 state->delta_cp_x = i_val;
2649 state->delta_cp_y = j_val;
2655 static drill_state_t *
2658 drill_state_t *state = g_new0(drill_state_t, 1);
2659 if (state != NULL) {
2661 state->curr_section = DRILL_NONE;
2662 state->coordinate_mode = DRILL_MODE_ABSOLUTE;
2663 state->origin_x = 0.0;
2664 state->origin_y = 0.0;
2666 state->backup_number_format = FMT_000_000;
2667 state->header_number_format = state->number_format = FMT_00_0000;
2669 state->decimals = 4;
2670 state->route_mode = DRILL_G_DRILL;
2671 state->tool_down = FALSE;
2682 read_double(gerb_file_t *fd, number_fmt_t fmt,
gerbv_omit_zeros_t omit_zeros,
int decimals)
2685 char temp[DRILL_READ_DOUBLE_SIZE];
2688 gboolean decimal_point = FALSE;
2689 gboolean sign_prepend = FALSE;
2691 memset(temp, 0,
sizeof(temp));
2693 read = gerb_fgetc(fd);
2694 while(read != EOF && i < (DRILL_READ_DOUBLE_SIZE -1) &&
2695 (isdigit(read) || read ==
'.' || read ==
',' || read ==
'+' || read ==
'-')) {
2696 if(read ==
',' || read ==
'.') decimal_point = TRUE;
2706 if(read ==
'-' || read ==
'+') {
2707 sign_prepend = TRUE;
2710 temp[i++] = (char)read;
2711 read = gerb_fgetc(fd);
2717 if (decimal_point) {
2718 result = strtod(temp, NULL);
2720 unsigned int wantdigits;
2722 char tmp2[DRILL_READ_DOUBLE_SIZE];
2724 memset(tmp2, 0,
sizeof(tmp2));
2747 wantdigits = decimals;
2752 fprintf(stderr, _(
"%s(): omit_zeros == GERBV_OMIT_ZEROS_TRAILING but fmt = %d.\n"
2753 "This should never have happened\n"), __FUNCTION__, fmt);
2767 if (wantdigits >
sizeof(tmp2) - 2) {
2768 fprintf(stderr, _(
"%s(): wantdigits = %d which exceeds the maximum allowed size\n"),
2769 __FUNCTION__, wantdigits);
2778 DPRINTF(
"%s(): wantdigits = %d, strlen(\"%s\") = %ld\n",
2779 __FUNCTION__, wantdigits, temp, (
long) strlen(temp));
2780 for (i = 0 ; i < wantdigits && i < strlen(temp) ; i++) {
2783 for ( ; i < wantdigits ; i++) {
2787 for ( ; i <= strlen(temp) ; i++) {
2788 tmp2[i] = temp[i-1];
2790 DPRINTF(
"%s(): After dealing with trailing zero suppression, convert \"%s\"\n", __FUNCTION__, tmp2);
2793 for (i = 0 ; i <= strlen(tmp2) && i <
sizeof (temp) ; i++) {
2818 scale = pow (10.0, -1.0*decimals);
2823 fprintf (stderr, _(
"%s(): Unhandled fmt ` %d\n"), __FUNCTION__, fmt);
2828 result = strtod(temp, NULL) * scale;
2831 if (!isfinite(result)) {
2835 DPRINTF(
" %s()=%f: fmt=%d, omit_zeros=%d, decimals=%d \n",
2836 __FUNCTION__, result, fmt, omit_zeros, decimals);
2845 eat_line(gerb_file_t *fd)
2850 read = gerb_fgetc(fd);
2851 }
while (read !=
'\n' && read !=
'\r' && read != EOF);
2862 eat_whitespace(gerb_file_t *fd)
2867 read = gerb_fgetc(fd);
2868 }
while ((read ==
' ' || read ==
'\t') && read != EOF);
2878 get_line(gerb_file_t *fd)
2882 gchar *tmps=g_strdup(
"");
2884 read = gerb_fgetc(fd);
2885 while (read !=
'\n' && read !=
'\r' && read != EOF) {
2886 retstring = g_strdup_printf(
"%s%c", tmps, read);
2894 read = gerb_fgetc(fd);
2912 file_check_str(gerb_file_t *fd,
const char *str)
2916 for (
int i = 0; str[i] !=
'\0'; i++) {
2943 return N_(
"rout mode");
2944 case DRILL_G_LINEARMOVE:
2945 return N_(
"linear mode");
2946 case DRILL_G_CWMOVE:
2947 return N_(
"circular CW mode");
2948 case DRILL_G_CCWMOVE:
2949 return N_(
"circular CCW mode");
2950 case DRILL_G_VARIABLEDWELL:
2951 return N_(
"variable dwell");
2953 return N_(
"drill mode");
2954 case DRILL_G_OVERRIDETOOLSPEED:
2955 return N_(
"override tool feed or speed");
2956 case DRILL_G_ROUTCIRCLE:
2957 return N_(
"routed CW circle");
2958 case DRILL_G_ROUTCIRCLECCW:
2959 return N_(
"routed CCW circle");
2960 case DRILL_G_VISTOOL:
2961 return N_(
"select vision tool");
2962 case DRILL_G_VISSINGLEPOINTOFFSET:
2963 return N_(
"single point vision offset");
2964 case DRILL_G_VISMULTIPOINTTRANS:
2965 return N_(
"multipoint vision translation");
2966 case DRILL_G_VISCANCEL:
2967 return N_(
"cancel vision translation or offset");
2968 case DRILL_G_VISCORRHOLEDRILL:
2969 return N_(
"vision corrected single hole drilling");
2970 case DRILL_G_VISAUTOCALIBRATION:
2971 return N_(
"vision system autocalibration");
2972 case DRILL_G_CUTTERCOMPOFF:
2973 return N_(
"cutter compensation off");
2974 case DRILL_G_CUTTERCOMPLEFT:
2975 return N_(
"cutter compensation left");
2976 case DRILL_G_CUTTERCOMPRIGHT:
2977 return N_(
"cutter compensation right");
2978 case DRILL_G_VISSINGLEPOINTOFFSETREL:
2979 return N_(
"single point vision relative offset");
2980 case DRILL_G_VISMULTIPOINTTRANSREL:
2981 return N_(
"multipoint vision relative translation");
2982 case DRILL_G_VISCANCELREL:
2983 return N_(
"cancel vision relative translation or offset");
2984 case DRILL_G_VISCORRHOLEDRILLREL:
2985 return N_(
"vision corrected single hole relative drilling");
2986 case DRILL_G_PACKDIP2:
2987 return N_(
"dual in line package");
2988 case DRILL_G_PACKDIP:
2989 return N_(
"dual in line package");
2990 case DRILL_G_PACK8PINL:
2991 return N_(
"eight pin L package");
2993 return N_(
"canned circle");
2995 return N_(
"canned slot");
2996 case DRILL_G_ROUTSLOT:
2997 return N_(
"routed step slot");
2998 case DRILL_G_ABSOLUTE:
2999 return N_(
"absolute input mode");
3000 case DRILL_G_INCREMENTAL:
3001 return N_(
"incremental input mode");
3002 case DRILL_G_ZEROSET:
3003 return N_(
"zero set");
3005 case DRILL_G_UNKNOWN:
3007 return N_(
"unknown G-code");
3017 return N_(
"end of program");
3018 case DRILL_M_PATTERNEND:
3019 return N_(
"pattern end");
3020 case DRILL_M_REPEATPATTERNOFFSET:
3021 return N_(
"repeat pattern offset");
3022 case DRILL_M_STOPOPTIONAL:
3023 return N_(
"stop optional");
3024 case DRILL_M_SANDREND:
3025 return N_(
"step and repeat end");
3026 case DRILL_M_STOPINSPECTION:
3027 return N_(
"stop for inspection");
3028 case DRILL_M_ZAXISROUTEPOSITIONDEPTHCTRL:
3029 return N_(
"Z-axis rout position with depth control");
3030 case DRILL_M_ZAXISROUTEPOSITION:
3031 return N_(
"Z-axis rout position");
3032 case DRILL_M_RETRACTCLAMPING:
3033 return N_(
"retract with clamping");
3034 case DRILL_M_RETRACTNOCLAMPING:
3035 return N_(
"retract without clamping");
3036 case DRILL_M_TOOLTIPCHECK:
3037 return N_(
"tool tip check");
3038 case DRILL_M_PATTERN:
3039 return N_(
"pattern start");
3040 case DRILL_M_ENDREWIND:
3041 return N_(
"end of program with rewind");
3042 case DRILL_M_MESSAGELONG:
3043 return N_(
"long operator message");
3044 case DRILL_M_MESSAGE:
3045 return N_(
"operator message");
3046 case DRILL_M_HEADER:
3047 return N_(
"header start");
3048 case DRILL_M_VISANDRPATTERN:
3049 return N_(
"vision step and repeat pattern start");
3050 case DRILL_M_VISANDRPATTERNREWIND:
3051 return N_(
"vision step and repeat rewind");
3052 case DRILL_M_VISANDRPATTERNOFFSETCOUNTERCTRL:
3053 return N_(
"vision step and repeat offset counter control");
3054 case DRILL_M_REFSCALING:
3055 return N_(
"reference scaling on");
3056 case DRILL_M_REFSCALINGEND:
3057 return N_(
"reference scaling off");
3058 case DRILL_M_PECKDRILLING:
3059 return N_(
"peck drilling on");
3060 case DRILL_M_PECKDRILLINGEND:
3061 return N_(
"peck drilling off");
3062 case DRILL_M_SWAPAXIS:
3063 return N_(
"swap axes");
3064 case DRILL_M_METRIC:
3065 return N_(
"metric measuring mode");
3066 case DRILL_M_IMPERIAL:
3067 return N_(
"inch measuring mode");
3068 case DRILL_M_MIRRORX:
3069 return N_(
"mirror image X-axis");
3070 case DRILL_M_MIRRORY:
3071 return N_(
"mirror image Y-axis");
3072 case DRILL_M_HEADEREND:
3073 return N_(
"header end");
3074 case DRILL_M_CANNEDTEXTX:
3075 return N_(
"canned text along X-axis");
3076 case DRILL_M_CANNEDTEXTY:
3077 return N_(
"canned text along Y-axis");
3078 case DRILL_M_USERDEFPATTERN:
3079 return N_(
"user defined stored pattern");
3081 case DRILL_M_UNKNOWN:
3083 return N_(
"unknown M-code");
Dynamic GUI window creation header info.
const char * drill_g_code_name(drill_g_code_t g_code)
Return drill G-code name by code number.
const char * drill_m_code_name(drill_m_code_t m_code)
Return drill M-code name by code number.
Header info for the Excellon drill parsing functions.
gerbv_drill_stats_t * gerbv_drill_stats_new(void)
Allocates a new drill_stats structure.
Header info to the statistics generating functions for Excellon drill files.
void gerbv_destroy_image(gerbv_image_t *image)
Free an image structure.
gerbv_image_t * gerbv_create_image(gerbv_image_t *image, const gchar *type)
Allocate a new gerbv_image structure.
Header info for the RS274X parsing functions.
The main header file for the libgerbv library.
@ GERBV_APERTURE_STATE_ON
@ GERBV_APERTURE_STATE_FLASH
@ GERBV_OMIT_ZEROS_TRAILING
@ GERBV_OMIT_ZEROS_EXPLICIT
@ GERBV_OMIT_ZEROS_LEADING
@ GERBV_OMIT_ZEROS_UNSPECIFIED
@ GERBV_INTERPOLATION_CW_CIRCULAR
@ GERBV_INTERPOLATION_CCW_CIRCULAR
@ GERBV_INTERPOLATION_LINEARx1
gerbv_layertype_t layertype
gerbv_drill_stats_t * drill_stats
gerbv_aperture_t * aperture[APERTURE_MAX]
gerbv_netstate_t * states
gerbv_image_info_t * info
gerbv_render_size_t boundingBox
gerbv_aperture_state_t aperture_state
gerbv_interpolation_t interpolation