47 #include <sys/types.h>
60 #define dprintf if(DEBUG) printf
63 #define DRILL_READ_DOUBLE_SIZE 32
66 DRILL_NONE, DRILL_HEADER, DRILL_DATA
67 } drill_file_section_t;
70 DRILL_MODE_ABSOLUTE, DRILL_MODE_INCREMENTAL
71 } drill_coordinate_mode_t;
74 DRILL_M_UNKNOWN, DRILL_M_NOT_IMPLEMENTED,
75 DRILL_M_END, DRILL_M_ENDREWIND,
76 DRILL_M_MESSAGE, DRILL_M_LONGMESSAGE,
77 DRILL_M_HEADER, DRILL_M_ENDHEADER,
78 DRILL_M_METRIC, DRILL_M_IMPERIAL,
79 DRILL_M_BEGINPATTERN, DRILL_M_ENDPATTERN,
80 DRILL_M_CANNEDTEXT, DRILL_M_TIPCHECK,
81 DRILL_M_METRICHEADER, DRILL_M_IMPERIALHEADER
85 DRILL_G_ABSOLUTE, DRILL_G_INCREMENTAL,
86 DRILL_G_ZEROSET, DRILL_G_UNKNOWN,
87 DRILL_G_ROUT, DRILL_G_DRILL,
89 DRILL_G_CWMOVE, DRILL_G_CCWMOVE,
101 typedef struct drill_state {
105 drill_file_section_t curr_section;
106 drill_coordinate_mode_t coordinate_mode;
116 number_fmt_t number_format, header_number_format;
118 number_fmt_t backup_number_format;
133 static drill_g_code_t drill_parse_G_code(gerb_file_t *fd,
gerbv_image_t *image);
134 static drill_m_code_t drill_parse_M_code(gerb_file_t *fd, drill_state_t *state,
136 static int drill_parse_T_code(gerb_file_t *fd, drill_state_t *state,
138 static void drill_parse_coordinate(gerb_file_t *fd,
char firstchar,
140 static drill_state_t *new_state(drill_state_t *state);
141 static double read_double(gerb_file_t *fd, number_fmt_t fmt,
143 static void eat_line(gerb_file_t *fd);
144 static char *get_line(gerb_file_t *fd);
157 static const char *supression_list[] = {
169 static const char *units_list[] = {
185 static gerbv_HID_Attribute drill_attribute_list[] = {
187 {N_(
"autodetect"), N_(
"Try to autodetect the file format"),
188 HID_Boolean, 0, 0, {1, 0, 0}, 0, 0},
190 {N_(
"zero_supression"), N_(
"Zero supression"),
191 HID_Enum, 0, 0, {0, 0, 0}, supression_list, 0},
193 {N_(
"units"), N_(
"Units"),
194 HID_Enum, 0, 0, {0, 0, 0}, units_list, 0},
196 {N_(
"digits"), N_(
"Number of digits. For trailing zero supression,"
197 " this is the number of digits before the decimal point. "
198 "Otherwise this is the number of digits after the decimal point."),
199 HID_Integer, 0, 20, {5, 0, 0}, 0, 0},
202 {
"tool_units",
"Tool size units",
203 HID_Enum, 0, 0, {0, 0, 0}, units_list, 0},
209 drill_attribute_merge (gerbv_HID_Attribute *dest,
int ndest, gerbv_HID_Attribute *src,
int nsrc)
218 for (i = 0 ; i < nsrc ; i++) {
221 while (j < ndest && strcmp (src[i].name, dest[j].name) != 0)
225 if (j < ndest && src[i].type == dest[j].type) {
226 dest[j].default_val = src[i].default_val;
238 drill_stats_increment_drill_counter(image->
drill_stats->drill_list,
239 state->current_tool);
242 if (curr_net->
next == NULL)
243 GERB_FATAL_ERROR(_(
"malloc curr_net->next failed"));
245 curr_net = curr_net->
next;
248 curr_net->
start_x = (double)state->curr_x;
249 curr_net->
start_y = (
double)state->curr_y;
262 curr_net->
aperture = state->current_tool;
270 if(image->
aperture[state->current_tool] == NULL)
274 image->
aperture[state->current_tool]->parameter[0] / 2;
276 image->
aperture[state->current_tool]->parameter[0] / 2;
278 image->
aperture[state->current_tool]->parameter[0] / 2;
280 image->
aperture[state->current_tool]->parameter[0] / 2;
283 min(image->
info->min_x,
285 image->
aperture[state->current_tool]->parameter[0] / 2));
287 min(image->
info->min_y,
289 image->
aperture[state->current_tool]->parameter[0] / 2));
291 max(image->
info->max_x,
293 image->
aperture[state->current_tool]->parameter[0] / 2));
295 max(image->
info->max_y,
297 image->
aperture[state->current_tool]->parameter[0] / 2));
304 parse_drillfile(gerb_file_t *fd, gerbv_HID_Attribute *attr_list,
int n_attr,
int reload)
306 drill_state_t *state = NULL;
319 setlocale(LC_NUMERIC,
"C" );
322 dprintf(
"In parse_drillfile, about to create image for this layer\n");
326 GERB_FATAL_ERROR(_(
"malloc image failed"));
328 if (reload && attr_list != NULL) {
332 image->
info->n_attr = n_attr;
333 image->
info->attr_list = gerbv_attribute_dup(attr_list, n_attr);
340 image->
info->n_attr =
sizeof (drill_attribute_list) /
sizeof (drill_attribute_list[0]);
341 image->
info->attr_list = gerbv_attribute_dup (drill_attribute_list, image->
info->n_attr);
344 drill_attribute_merge (image->
info->attr_list, image->
info->n_attr,
354 GERB_FATAL_ERROR(_(
"malloc stats failed"));
358 state = new_state(state);
360 GERB_FATAL_ERROR(_(
"malloc state failed"));
363 if (image->
format == NULL)
364 GERB_FATAL_ERROR(_(
"malloc format failed"));
368 if (!image->
info->attr_list[HA_auto].default_val.int_value) {
370 state->number_format = FMT_USER;
371 state->decimals = image->
info->attr_list[HA_digits].default_val.int_value;
372 if (image->
info->attr_list[HA_xy_units].default_val.int_value == UNITS_MM)
374 switch (image->
info->attr_list[HA_supression].default_val.int_value) {
389 dprintf(
"%s(): Starting parsing of drill file\n", __FUNCTION__);
390 while ((read = gerb_fgetc(fd)) != EOF) {
392 switch ((
char) read) {
399 tmps = get_line (fd);
400 if (strcmp (tmps,
"DETECT,ON") == 0 ||
401 strcmp (tmps,
"DETECT,OFF") == 0) {
404 if (strcmp (tmps,
"DETECT,ON") == 0)
411 tmps2 = g_strdup_printf (
"%s\n%s", stats->detect, tmps3);
412 g_free (stats->detect);
414 tmps2 = g_strdup_printf (
"%s", tmps3);
416 stats->detect = tmps2;
418 string = g_strdup_printf(_(
"Undefined header line = '%s'\n"),tmps);
419 drill_stats_add_error(stats->error_list,
429 tmps = get_line (fd);
431 if (strcmp (tmps,
"FMAT,2") != 0) {
432 string = g_strdup_printf(_(
"Undefined header line = '%s'\n"),tmps);
433 drill_stats_add_error(stats->error_list,
444 switch (drill_parse_G_code(fd, image)) {
446 drill_stats_add_error(stats->error_list,
448 _(
"Rout mode data is not supported\n"),
455 if ((read = gerb_fgetc(fd)) != EOF) {
456 drill_parse_coordinate(fd, read, image, state);
459 curr_net->
stop_x = (double)state->curr_x;
460 curr_net->
stop_y = (
double)state->curr_y;
468 drill_stats_add_error(stats->error_list,
469 -1, _(
"Unexpected EOF found.\n"),
473 case DRILL_G_ABSOLUTE :
474 state->coordinate_mode = DRILL_MODE_ABSOLUTE;
476 case DRILL_G_INCREMENTAL :
477 state->coordinate_mode = DRILL_MODE_INCREMENTAL;
479 case DRILL_G_ZEROSET :
480 if((read = gerb_fgetc(fd)) == EOF)
481 drill_stats_add_error(stats->error_list,
483 _(
"Unexpected EOF found.\n"),
485 drill_parse_coordinate(fd, (
char)read, image, state);
486 state->origin_x = state->curr_x;
487 state->origin_y = state->curr_y;
495 if (state->curr_section != DRILL_HEADER)
498 int c = gerb_fgetc(fd);
501 if (
'C' == gerb_fgetc(fd)) {
502 if (
'H' == gerb_fgetc(fd)) {
506 if (
',' == gerb_fgetc(fd)) {
508 if (c != EOF &&
'Z' == gerb_fgetc(fd)) {
513 state->header_number_format =
514 state->number_format = FMT_00_0000;
522 state->header_number_format =
523 state->number_format = FMT_00_0000;
529 drill_stats_add_error(stats->error_list,
531 _(
"Found junk after INCH command\n"),
536 drill_stats_add_error(stats->error_list,
538 _(
"Found junk after INCH command\n"),
549 if (
'I' == gerb_fgetc(fd))
550 if (
',' == gerb_fgetc(fd))
551 if (
'O' == gerb_fgetc(fd)) {
552 if (
'N' == (c = gerb_fgetc(fd)))
553 state->coordinate_mode = DRILL_MODE_INCREMENTAL;
554 else if (
'F' == c)
if (
'F' == gerb_fgetc(fd))
555 state->coordinate_mode = DRILL_MODE_ABSOLUTE;
564 switch(drill_parse_M_code(fd, state, image)) {
565 case DRILL_M_HEADER :
566 state->curr_section = DRILL_HEADER;
568 case DRILL_M_ENDHEADER :
569 state->curr_section = DRILL_DATA;
580 drill_stats_add_error(stats->error_list,
582 _(
"End of Excellon header reached but no leading/trailing zero handling specified.\n"),
584 drill_stats_add_error(stats->error_list,
586 _(
"Assuming leading zeros.\n"),
591 case DRILL_M_METRIC :
593 state->curr_section != DRILL_HEADER) {
594 drill_stats_add_error(stats->error_list,
596 _(
"M71 code found but no METRIC specification in header.\n"),
598 drill_stats_add_error(stats->error_list,
600 _(
"Assuming all tool sizes are MM.\n"),
605 for (tool_num = TOOL_MIN; tool_num < TOOL_MAX; tool_num++) {
609 size = image->
aperture[tool_num]->parameter[0];
610 drill_stats_modify_drill_list(stats->drill_list,
617 image->
aperture[tool_num]->parameter[0] /= 25.4;
622 state->number_format = state->backup_number_format;
626 case DRILL_M_IMPERIAL :
628 if (state->number_format != FMT_00_0000)
630 state->backup_number_format = state->number_format;
631 state->number_format = FMT_00_0000;
637 case DRILL_M_LONGMESSAGE :
638 case DRILL_M_MESSAGE :
639 case DRILL_M_CANNEDTEXT :
641 string = g_strdup_printf(_(
"Message embedded in drill file: '%s'\n"),
643 drill_stats_add_error(stats->error_list,
649 case DRILL_M_NOT_IMPLEMENTED :
650 case DRILL_M_ENDPATTERN :
651 case DRILL_M_TIPCHECK :
656 case DRILL_M_ENDREWIND :
657 goto drill_parse_end;
659 case DRILL_M_METRICHEADER :
663 drill_stats_add_error(stats->error_list,
665 _(
"Undefined M code found.\n"),
671 if(state->curr_section == DRILL_HEADER) {
672 drill_stats_add_error(stats->error_list,
674 _(
"R codes are not allowed in the header.\n"),
677 double start_x, start_y;
678 double step_x, step_y;
694 start_x = state->curr_x;
695 start_y = state->curr_y;
702 while (
'0' <= c && c <=
'9') {
703 rcnt = 10*rcnt + (c -
'0');
706 dprintf (
"working on R code (repeat) with a number of reps equal to %d\n", rcnt);
710 step_x = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
716 step_y = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
721 dprintf (
"Getting ready to repeat the drill %d times with delta_x = %g, delta_y = %g\n", rcnt, step_x, step_y);
724 for (c = 1 ; c <= rcnt ; c++) {
725 state->curr_x = start_x + c*step_x;
726 state->curr_y = start_y + c*step_y;
727 dprintf (
" Repeat #%d -- new location is (%g, %g)\n", c, state->curr_x, state->curr_y);
728 curr_net = drill_add_drill_hole (image, state, stats, curr_net);
734 drill_stats_add_error(stats->error_list,
736 _(
"Drill file sets spindle speed -- ignoring.\n"),
741 drill_parse_T_code(fd, state, image);
745 tmps = get_line (fd);
747 if (strcmp (tmps,
"VER,1") != 0) {
748 string = g_strdup_printf(_(
"Undefined header line = '%s'\n"),tmps);
749 drill_stats_add_error(stats->error_list,
751 g_strdup_printf(_(
"Undefined header line = '%s'\n"),tmps),
761 drill_parse_coordinate(fd, read, image, state);
764 curr_net = drill_add_drill_hole (image, state, stats, curr_net);
768 state->curr_section = DRILL_DATA;
776 if(state->curr_section == DRILL_HEADER) {
778 drill_stats_add_error(stats->error_list,
780 _(
"Undefined codes found in header.\n"),
784 string = g_strdup_printf(_(
"Undefined header line = '%s'\n"),
786 drill_stats_add_error(stats->error_list,
793 string = g_strdup_printf(_(
"Undefined character '%c' [0x%02x] found inside data, ignoring\n"),
795 drill_stats_add_error(stats->error_list,
803 drill_stats_add_error(stats->error_list,
805 _(
"No EOF found in drill file.\n"),
809 dprintf (
"%s(): Populating file attributes\n", __FUNCTION__);
811 switch (state->unit) {
813 image->
info->attr_list[HA_xy_units].default_val.int_value = UNITS_MM;
817 image->
info->attr_list[HA_xy_units].default_val.int_value = UNITS_INCH;
821 switch (state->number_format) {
824 image->
info->attr_list[HA_digits].default_val.int_value = 2;
828 image->
info->attr_list[HA_digits].default_val.int_value = 3;
832 image->
info->attr_list[HA_digits].default_val.int_value = 4;
836 dprintf (
"%s(): Keeping user specified number of decimal places (%d)\n",
838 image->
info->attr_list[HA_digits].default_val.int_value);
845 switch (image->
format->omit_zeros) {
847 image->
info->attr_list[HA_supression].default_val.int_value = SUP_LEAD;
851 image->
info->attr_list[HA_supression].default_val.int_value = SUP_TRAIL;
855 image->
info->attr_list[HA_supression].default_val.int_value = SUP_NONE;
871 drill_file_p(gerb_file_t *fd, gboolean *returnFoundBinary)
873 char *buf=NULL, *tbuf;
880 gboolean found_binary = FALSE;
881 gboolean found_M48 = FALSE;
882 gboolean found_M30 = FALSE;
883 gboolean found_percent = FALSE;
884 gboolean found_T = FALSE;
885 gboolean found_X = FALSE;
886 gboolean found_Y = FALSE;
887 gboolean end_comments=FALSE;
889 tbuf = g_malloc(MAXL);
891 GERB_FATAL_ERROR(_(
"malloc buf failed while checking for drill file."));
893 while (fgets(tbuf, MAXL, fd->fd) != NULL) {
898 if(g_strstr_len(buf, len,
";")!=NULL){
899 for (i=0;i<len-1;++i){
900 if(buf[i]==
'\n' && buf[i+1] !=
';' && buf[i+1] !=
'\r' && buf[i+1] !=
'\n'){
916 for (i = 0; i < len; i++) {
917 ascii = (int) buf[i];
918 if ((ascii > 128) || (ascii < 0)) {
924 if (g_strstr_len(buf, len,
"M48")) {
929 if (g_strstr_len(buf, len,
"M30")) {
936 if ((letter = g_strstr_len(buf, len,
"%")) != NULL) {
937 if ((letter[1] ==
'\r') || (letter[1] ==
'\n'))
938 found_percent = TRUE;
942 if ((letter = g_strstr_len(buf, len,
"T")) != NULL) {
943 if (!found_T && (found_X || found_Y)) {
946 if (isdigit( (
int) letter[1])) {
953 if ((letter = g_strstr_len(buf, len,
"X")) != NULL) {
954 ascii = (int) letter[1];
955 if ((ascii >= zero) && (ascii <= nine)) {
959 if ((letter = g_strstr_len(buf, len,
"Y")) != NULL) {
960 ascii = (int) letter[1];
961 if ((ascii >= zero) && (ascii <= nine)) {
969 *returnFoundBinary = found_binary;
972 if ( ((found_X || found_Y) && found_T) &&
973 (found_M48 || (found_percent && found_M30)) )
975 else if (found_M48 && found_T && found_percent && found_M30)
989 drill_parse_T_code(gerb_file_t *fd, drill_state_t *state,
gerbv_image_t *image)
992 gboolean done = FALSE;
1001 temp = gerb_fgetc(fd);
1002 dprintf(
"Found a char %d after the T\n", temp);
1005 if((temp ==
'C') && ((fd->ptr + 2) < fd->datalen)){
1006 if(gerb_fgetc(fd) ==
'S'){
1007 if (gerb_fgetc(fd) ==
'T' ){
1009 tmps = get_line(fd++);
1010 string = g_strdup_printf(_(
"Tool change stop switch found: %s\n"), tmps);
1011 drill_stats_add_error(stats->error_list,
1024 if( !(isdigit(temp) != 0 || temp ==
'+' || temp ==
'-') ) {
1026 drill_stats_add_error(stats->error_list,
1028 _(
"Orcad bug: Junk text found in place of tool definition.\n"),
1030 tmps = get_line(fd);
1031 string = g_strdup_printf(_(
"Junk text = %s\n"),
1033 drill_stats_add_error(stats->error_list,
1039 drill_stats_add_error(stats->error_list,
1041 _(
"Ignorning junk text.\n"),
1048 tool_num = (int) gerb_fgetint(fd, NULL);
1049 dprintf (
"In %s: handling tool_num = %d\n", __FUNCTION__, tool_num);
1054 if ( (tool_num < TOOL_MIN) || (tool_num >= TOOL_MAX) ) {
1055 string = g_strdup_printf(_(
"Drill number out of bounds: %d.\n"), tool_num);
1056 drill_stats_add_error(stats->error_list,
1064 state->current_tool = tool_num;
1067 temp = gerb_fgetc(fd);
1073 switch((
char)temp) {
1076 dprintf (
"%s: Read a size of %g %s\n", __FUNCTION__, size,
1080 }
else if(size >= 4.0) {
1086 string = g_strdup_printf(_(
"Read a drill of diameter %g inches.\n"), size);
1087 drill_stats_add_error(stats->error_list,
1092 string = g_strdup_printf(_(
"Assuming units are mils.\n"));
1093 drill_stats_add_error(stats->error_list,
1101 if(size <= 0. || size >= 10000.) {
1102 string = g_strdup_printf(_(
"Unreasonable drill size found for drill %d: %g\n"), tool_num, size);
1103 drill_stats_add_error(stats->error_list,
1109 if(image->
aperture[tool_num] != NULL) {
1114 if (image->
aperture[tool_num]->parameter[0] != size ||
1116 image->
aperture[tool_num]->nuf_parameters != 1 ||
1118 string = g_strdup_printf(_(
"Found redefinition of drill %d.\n"), tool_num);
1119 drill_stats_add_error(stats->error_list,
1127 (gerbv_aperture_t *)g_malloc0(
sizeof(gerbv_aperture_t));
1128 if (image->
aperture[tool_num] == NULL)
1129 GERB_FATAL_ERROR(_(
"malloc tool failed"));
1134 image->
aperture[tool_num]->parameter[0] = size;
1136 image->
aperture[tool_num]->nuf_parameters = 1;
1144 string = g_strdup_printf(
"%s", (state->unit ==
GERBV_UNIT_MM ? _(
"mm") : _(
"inch")));
1145 drill_stats_add_to_drill_list(stats->drill_list,
1155 gerb_fgetint(fd, NULL);
1166 if( (temp = gerb_fgetc(fd)) == EOF) {
1167 drill_stats_add_error(stats->error_list,
1169 _(
"Unexpected EOF encountered header of drill file.\n"),
1176 if(image->
aperture[tool_num] == NULL) {
1180 (gerbv_aperture_t *)g_malloc0(
sizeof(gerbv_aperture_t));
1181 if (image->
aperture[tool_num] == NULL)
1182 GERB_FATAL_ERROR(_(
"malloc tool failed"));
1185 dia = gerbv_get_tool_diameter(tool_num);
1191 dia = (double)(16 + 8 * tool_num) / 1000;
1198 string = g_strdup_printf(_(
"Tool %02d used without being defined\n"), tool_num);
1199 drill_stats_add_error(stats->error_list,
1204 string = g_strdup_printf(_(
"Setting a default size of %g\"\n"), dia);
1205 drill_stats_add_error(stats->error_list,
1214 image->
aperture[tool_num]->nuf_parameters = 1;
1215 image->
aperture[tool_num]->parameter[0] = dia;
1219 if (tool_num != 0) {
1222 string = g_strdup_printf(
"%s",
1224 drill_stats_add_to_drill_list(stats->drill_list,
1237 static drill_m_code_t
1238 drill_parse_M_code(gerb_file_t *fd, drill_state_t *state,
gerbv_image_t *image)
1243 drill_m_code_t result = DRILL_M_UNKNOWN;
1245 dprintf(
"---> entering drill_parse_M_code ...\n");
1247 read[0] = gerb_fgetc(fd);
1248 read[1] = gerb_fgetc(fd);
1250 if ((read[0] == EOF) || (read[1] == EOF))
1251 drill_stats_add_error(stats->error_list,
1253 _(
"Unexpected EOF found while parsing M code.\n"),
1255 op[0] = read[0], op[1] = read[1], op[2] = 0;
1257 if (strncmp(op,
"00", 2) == 0) {
1259 result = DRILL_M_END;
1260 }
else if (strncmp(op,
"01", 2) == 0) {
1262 result = DRILL_M_ENDPATTERN;
1263 }
else if (strncmp(op,
"18", 2) == 0) {
1265 result = DRILL_M_TIPCHECK;
1266 }
else if (strncmp(op,
"25", 2) == 0) {
1268 result = DRILL_M_BEGINPATTERN;
1269 }
else if (strncmp(op,
"31", 2) == 0) {
1271 result = DRILL_M_BEGINPATTERN;
1272 }
else if (strncmp(op,
"30", 2) == 0) {
1274 result = DRILL_M_ENDREWIND;
1275 }
else if (strncmp(op,
"45", 2) == 0) {
1277 result = DRILL_M_LONGMESSAGE;
1278 }
else if (strncmp(op,
"47", 2) == 0) {
1280 result = DRILL_M_MESSAGE;
1281 }
else if (strncmp(op,
"48", 2) == 0) {
1283 result = DRILL_M_HEADER;
1284 }
else if (strncmp(op,
"71", 2) == 0) {
1287 result = DRILL_M_METRIC;
1288 }
else if (strncmp(op,
"72", 2) == 0) {
1291 result = DRILL_M_IMPERIAL;
1292 }
else if (strncmp(op,
"95", 2) == 0) {
1294 result = DRILL_M_ENDHEADER;
1295 }
else if (strncmp(op,
"97", 2) == 0) {
1297 result = DRILL_M_CANNEDTEXT;
1298 }
else if (strncmp(op,
"98", 2) == 0) {
1300 return DRILL_M_CANNEDTEXT;
1301 }
else if (state->curr_section == DRILL_HEADER &&
1302 strncmp(op,
"ET", 2) == 0) {
1309 if (
'R' == gerb_fgetc(fd) &&
1310 'I' == gerb_fgetc(fd) &&
1311 'C' == gerb_fgetc(fd)) {
1313 if (
',' == gerb_fgetc(fd)) {
1317 switch ((c = gerb_fgetc(fd))) {
1320 if (
'Z' != gerb_fgetc(fd))
1324 dprintf (
"%s(): Detected a file that probably has trailing zero supression\n", __FUNCTION__);
1332 dprintf (
"%s(): Detected a file that probably has leading zero supression\n", __FUNCTION__);
1344 state->header_number_format =
1345 state->number_format = FMT_000_000;
1346 state->decimals = 3;
1356 if (
'0' != gerb_fgetc(fd) ||
1357 '0' != gerb_fgetc(fd))
1361 read[0] = gerb_fgetc(fd);
1362 read[1] = gerb_fgetc(fd);
1363 if (read[0] == EOF || read[1] == EOF)
1367 if (strcmp(op,
"0.") == 0) {
1370 if (
'0' != gerb_fgetc(fd) ||
1371 '0' != gerb_fgetc(fd))
1376 state->number_format = FMT_0000_00;
1377 state->decimals = 2;
1381 if (strcmp(op,
".0") != 0)
1385 if (
'0' != gerb_fgetc(fd))
1387 if (
'0' == gerb_fgetc(fd) && state->autod)
1389 state->number_format = FMT_000_000;
1390 state->decimals = 3;
1396 state->number_format = FMT_000_00;
1397 state->decimals = 2;
1405 drill_stats_add_error(stats->error_list,
1407 _(
"Found junk after METRIC command\n"),
1418 return DRILL_M_METRICHEADER;
1422 result = DRILL_M_UNKNOWN;
1425 dprintf(
"<---- ...leaving drill_parse_M_code.\n");
1431 static drill_g_code_t
1437 drill_g_code_t result;
1439 dprintf(
"---> entering drill_parse_G_code ...\n");
1441 read[0] = gerb_fgetc(fd);
1442 read[1] = gerb_fgetc(fd);
1444 if ((read[0] == EOF) || (read[1] == EOF)) {
1445 drill_stats_add_error(stats->error_list,
1447 _(
"Unexpected EOF found while parsing G code.\n"),
1451 op[0] = read[0], op[1] = read[1], op[2] = 0;
1453 if (strncmp(op,
"00", 2) == 0) {
1455 result = DRILL_G_ROUT;
1456 }
else if (strncmp(op,
"01", 2) == 0) {
1458 result = DRILL_G_LINEARMOVE;
1459 }
else if (strncmp(op,
"02", 2) == 0) {
1461 result = DRILL_G_CWMOVE;
1462 }
else if (strncmp(op,
"03", 2) == 0) {
1464 result = DRILL_G_CCWMOVE;
1465 }
else if (strncmp(op,
"05", 2) == 0) {
1467 result = DRILL_G_DRILL;
1468 }
else if (strncmp(op,
"85", 2) == 0) {
1470 result = DRILL_G_SLOT;
1471 }
else if (strncmp(op,
"90", 2) == 0) {
1473 result = DRILL_G_ABSOLUTE;
1474 }
else if (strncmp(op,
"91", 2) == 0) {
1476 result = DRILL_G_INCREMENTAL;
1477 }
else if (strncmp(op,
"93", 2) == 0) {
1479 result = DRILL_G_ZEROSET;
1482 result = DRILL_G_UNKNOWN;
1485 dprintf(
"<---- ...leaving drill_parse_G_code.\n");
1495 drill_parse_coordinate(gerb_file_t *fd,
char firstchar,
1500 if(state->coordinate_mode == DRILL_MODE_ABSOLUTE) {
1501 if(firstchar ==
'X') {
1502 state->curr_x = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
1503 if((read = (
char)gerb_fgetc(fd)) ==
'Y') {
1504 state->curr_y = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
1507 state->curr_y = read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
1509 }
else if(state->coordinate_mode == DRILL_MODE_INCREMENTAL) {
1510 if(firstchar ==
'X') {
1511 state->curr_x += read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
1512 if((read = (
char)gerb_fgetc(fd)) ==
'Y') {
1513 state->curr_y += read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
1516 state->curr_y += read_double(fd, state->number_format, image->
format->omit_zeros, state->decimals);
1525 static drill_state_t *
1526 new_state(drill_state_t *state)
1528 state = (drill_state_t *)g_malloc0(
sizeof(drill_state_t));
1529 if (state != NULL) {
1531 state->curr_section = DRILL_NONE;
1532 state->coordinate_mode = DRILL_MODE_ABSOLUTE;
1533 state->origin_x = 0.0;
1534 state->origin_y = 0.0;
1536 state->backup_number_format = FMT_000_000;
1537 state->header_number_format = state->number_format = FMT_00_0000;
1539 state->decimals = 4;
1550 read_double(gerb_file_t *fd, number_fmt_t fmt,
gerbv_omit_zeros_t omit_zeros,
int decimals)
1553 char temp[DRILL_READ_DOUBLE_SIZE];
1554 int i = 0, ndigits = 0;
1556 gboolean decimal_point = FALSE;
1557 gboolean sign_prepend = FALSE;
1559 dprintf(
"%s(%p, %d, %d, %d)\n", __FUNCTION__, fd, fmt, omit_zeros, decimals);
1561 memset(temp, 0,
sizeof(temp));
1563 read = gerb_fgetc(fd);
1564 while(read != EOF && i < (DRILL_READ_DOUBLE_SIZE -1) &&
1565 (isdigit(read) || read ==
'.' || read ==
',' || read ==
'+' || read ==
'-')) {
1566 if(read ==
',' || read ==
'.') decimal_point = TRUE;
1575 if(isdigit(read)) ndigits++;
1577 if(read ==
'-' || read ==
'+')
1578 sign_prepend = TRUE;
1580 temp[i++] = (char)read;
1581 read = gerb_fgetc(fd);
1586 if (decimal_point) {
1587 result = strtod(temp, NULL);
1591 char tmp2[DRILL_READ_DOUBLE_SIZE];
1593 memset(tmp2, 0,
sizeof(tmp2));
1595 dprintf(
"%s(): omit_zeros = %d, fmt = %d\n", __FUNCTION__, omit_zeros, fmt);
1617 wantdigits = decimals;
1622 fprintf(stderr, _(
"%s(): omit_zeros == GERBV_OMIT_ZEROS_TRAILING but fmt = %d.\n"
1623 "This should never have happened\n"), __FUNCTION__, fmt);
1636 if (wantdigits >
sizeof(tmp2) - 2) {
1637 fprintf(stderr, _(
"%s(): wantdigits = %d which exceeds the maximum allowed size\n"),
1638 __FUNCTION__, wantdigits);
1647 dprintf(
"%s(): wantdigits = %d, strlen(\"%s\") = %ld\n",
1648 __FUNCTION__, wantdigits, temp, (
long) strlen(temp));
1649 for (i = 0 ; i < wantdigits && i < strlen(temp) ; i++) {
1652 for ( ; i < wantdigits ; i++) {
1656 for ( ; i <= strlen(temp) ; i++) {
1657 tmp2[i] = temp[i-1];
1659 dprintf(
"%s(): After dealing with trailing zero supression, convert \"%s\"\n", __FUNCTION__, tmp2);
1662 for (i = 0 ; i <= strlen(tmp2) && i <
sizeof (temp) ; i++) {
1687 scale = pow (10.0, -1.0*decimals);
1692 fprintf (stderr, _(
"%s(): Unhandled fmt ` %d\n"), __FUNCTION__, fmt);
1697 result = strtod(temp, NULL) * scale;
1708 eat_line(gerb_file_t *fd)
1710 int read = gerb_fgetc(fd);
1712 while(read != 10 && read != 13) {
1713 if (read == EOF)
return;
1714 read = gerb_fgetc(fd);
1720 get_line(gerb_file_t *fd)
1722 int read = gerb_fgetc(fd);
1724 gchar *tmps=g_strdup(
"");
1726 while(read != 10 && read != 13) {
1729 retstring = g_strdup_printf(
"%s%c", tmps, read);
1737 read = gerb_fgetc(fd);