/**************************************************************************** * * * Character Received - add it to our command * * * ****************************************************************************/ void gcode_parse_char(uint8_t c) { uint8_t save_ch; #ifdef ASTERISK_IN_CHECKSUM_INCLUDED if (next_target.seen_checksum == 0) { next_target.checksum_calculated = crc(next_target.checksum_calculated, c); } #endif save_ch = c; // uppercase if (c >= 'a' && c <= 'z') { c &= ~32; } // process previous field if (last_field) { // check if we're seeing a new field or end of line // any character will start a new field, even invalid/unknown ones if ((c >= 'A' && c <= 'Z') || c == '*' || (c == 10) || (c == 13)) { // before using value, apply the sign if (read_digit.sign) { value = -value; } switch (last_field) { case 'G': next_target.G = value; break; case 'M': next_target.M = value; // this is a bit hacky since string parameters don't fit in general G code syntax // NB: filename MUST start with a letter and MUST NOT contain spaces // letters will also be converted to uppercase if ((next_target.M == 23) || (next_target.M == 28)) { next_target.getting_string = 1; } break; case 'X': if (next_target.option_inches) { next_target.target.x = inch_to_mm(value); } else { next_target.target.x = value; } break; case 'Y': if (next_target.option_inches) { next_target.target.y = inch_to_mm(value); } else { next_target.target.y = value; } break; case 'Z': if (next_target.option_inches) { next_target.target.z = inch_to_mm(value); } else { next_target.target.z = value; } break; case 'E': if (next_target.option_inches) { next_target.target.e = inch_to_mm(value); } else { next_target.target.e = value; } break; case 'F': if (next_target.option_inches) { next_target.target.feed_rate = inch_to_mm(value); } else { next_target.target.feed_rate = value; } break; case 'S': next_target.S = value; break; case 'P': // if this is dwell, multiply by 1000 to convert seconds to milliseconds if (next_target.G == 4) { next_target.P = value * 1000.0; } else { next_target.P = value; } break; case 'N': next_target.N = value; break; case '*': next_target.checksum_read = value; break; } // reset for next field last_field = 0; read_digit.sign = read_digit.exponent = 0; value = 0; } } if (next_target.getting_string) { if ((c == 10) || (c == 13) || ( c == ' ') || ( c == '*')) { next_target.getting_string = 0; } else { if (next_target.chpos < sizeof(next_target.filename)) { next_target.filename [next_target.chpos++] = c; next_target.filename [next_target.chpos] = 0; } } } // skip comments, filenames if (next_target.seen_semi_comment == 0 && next_target.seen_parens_comment == 0 && next_target.getting_string == 0) { // new field? if ((c >= 'A' && c <= 'Z') || c == '*') { last_field = c; } // process character switch (c) { // each currently known command is either G or M, so preserve previous G/M unless a new one has appeared // FIXME: same for T command case 'G': next_target.seen_G = 1; next_target.seen_M = 0; next_target.M = 0; break; case 'M': next_target.seen_M = 1; next_target.seen_G = 0; next_target.G = 0; break; case 'X': next_target.seen_X = 1; break; case 'Y': next_target.seen_Y = 1; break; case 'Z': next_target.seen_Z = 1; break; case 'E': next_target.seen_E = 1; break; case 'F': next_target.seen_F = 1; break; case 'S': next_target.seen_S = 1; break; case 'P': next_target.seen_P = 1; break; case 'N': next_target.seen_N = 1; break; case '*': next_target.seen_checksum = 1; break; // comments case ';': case '^': next_target.seen_semi_comment = 1; break; case '(': next_target.seen_parens_comment = 1; break; // now for some numeracy case '-': read_digit.sign = 1; // force sign to be at start of number, so 1-2 = -2 instead of -12 read_digit.exponent = 0; break; case '.': if (read_digit.exponent == 0) { read_digit.exponent = 1; } break; default: // can't do ranges in switch..case, so process actual digits here if (c >= '0' && c <= '9') { if (read_digit.exponent == 0) { value = value * 10 + (c - '0'); } else { value += (double)(c - '0') / power(10, read_digit.exponent); } if (read_digit.exponent) { read_digit.exponent++; } } } } else if (next_target.seen_parens_comment == 1 && c == ')') { next_target.seen_parens_comment = 0; // recognize stuff after a (comment) } #ifndef ASTERISK_IN_CHECKSUM_INCLUDED if (next_target.seen_checksum == 0) { next_target.checksum_calculated = crc(next_target.checksum_calculated, save_ch); } #endif }
static char* convert_page_size_name( char *pValue ) { int i; char *pOptName = NULL; char *pDup = NULL; for( i=0; gluecode_page_name_table[i].glue_name!=NULL; i++ ){ if( !strcmp(gluecode_page_name_table[i].glue_name, pValue) ){ pOptName = &gluecode_page_name_table[i].opt_name[0]; return pOptName; } } if( !strncmp(pValue, "custom", 6) ){ char *pTemp; char *pWidth, *pHeight; int width_mm, height_mm; short flgInch; pDup = strdup(pValue); pTemp = strrchr(pDup, '_'); if( pTemp ){ pTemp++; pWidth = pTemp; while( *pTemp != '\0' && *pTemp != 'x') pTemp++; if( *pTemp == 'x' ){ *pTemp = '\0';pTemp++; pHeight = pTemp; while( isdigit(*pTemp) ) pTemp++; if( !strcmp(pTemp, "in") ){ flgInch = 1; }else if( !strcmp(pTemp, "mm") ){ flgInch = 0; }else{ goto opt_error; } *pTemp = '\0'; if( flgInch ){ int width_in, height_in; width_in = atoi(pWidth); height_in = atoi(pHeight); width_mm = inch_to_mm(width_in); height_mm = inch_to_mm(height_in); }else{ width_mm = atoi(pWidth); height_mm = atoi(pHeight); } for( i=0; gluecode_page_size_table[i].opt_name!=NULL; i++ ){ if( width_mm == gluecode_page_size_table[i].width && height_mm == gluecode_page_size_table[i].height ){ pOptName = &gluecode_page_size_table[i].opt_name[0]; break; } } return pOptName; } } } opt_error: if( pDup ) free(pDup); return NULL; }