report error message when a command was not taken
[clinton/Smoothieware.git] / src / modules / communication / utils / Gcode.cpp
CommitLineData
df27a6a3 1/*
cd011f58
AW
2 This file is part of Smoothie (http://smoothieware.org/). The motion control part is heavily based on Grbl (https://github.com/simen/grbl).
3 Smoothie is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
4 Smoothie is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
df27a6a3 5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
cd011f58
AW
6*/
7
8
4cff3ded
AW
9#include <string>
10using std::string;
11#include "Gcode.h"
838b33b4 12#include "libs/StreamOutput.h"
adc927a8 13#include "utils.h"
838b33b4 14
838b33b4 15#include <stdlib.h>
4cff3ded 16
edac9072
AW
17// This is a gcode object. It reprensents a GCode string/command, an caches some important values about that command for the sake of performance.
18// It gets passed around in events, and attached to the queue ( that'll change )
00669816 19Gcode::Gcode(const string& command, StreamOutput* stream) : command(command), m(0), g(0), add_nl(false), stream(stream) {
702023f3 20 prepare_cached_values();
d149c730 21 this->millimeters_of_travel = 0L;
74b6303c 22 this->accepted_by_module=false;
702023f3 23}
4cff3ded 24
e55e3062
AW
25Gcode::Gcode(const Gcode& to_copy){
26 this->command.assign( to_copy.command );
27 this->millimeters_of_travel = to_copy.millimeters_of_travel;
28 this->has_m = to_copy.has_m;
29 this->has_g = to_copy.has_g;
30 this->m = to_copy.m;
31 this->g = to_copy.g;
32 this->add_nl = to_copy.add_nl;
33 this->stream = to_copy.stream;
74b6303c 34 this->accepted_by_module=false;
e55e3062
AW
35}
36
37Gcode& Gcode::operator= (const Gcode& to_copy){
38 if( this != &to_copy ){
39 this->command.assign( to_copy.command );
40 this->millimeters_of_travel = to_copy.millimeters_of_travel;
41 this->has_m = to_copy.has_m;
42 this->has_g = to_copy.has_g;
43 this->m = to_copy.m;
44 this->g = to_copy.g;
45 this->add_nl = to_copy.add_nl;
46 this->stream = to_copy.stream;
47 }
74b6303c 48 this->accepted_by_module=false;
e55e3062
AW
49 return *this;
50}
51
52
2bb8b390 53// Whether or not a Gcode has a letter
4cff3ded 54bool Gcode::has_letter( char letter ){
13e4a3f9 55 //return ( this->command->find( letter ) != string::npos );
f36ddd7d
BG
56 for (std::string::const_iterator c = this->command.cbegin(); c != this->command.cend(); c++) {
57 if( *c == letter ){
13e4a3f9
AW
58 return true;
59 }
60 }
61 return false;
4cff3ded
AW
62}
63
13e4a3f9
AW
64// Retrieve the value for a given letter
65// We don't use the high-level methods of std::string because they call malloc and it's very bad to do that inside of interrupts
4cff3ded 66double Gcode::get_value( char letter ){
838b33b4 67 //__disable_irq();
cf67ed1b
MM
68 const char* cs = command.c_str();
69 char* cn = NULL;
70 for (; *cs; cs++){
71 if( letter == *cs ){
72 cs++;
73 double r = strtod(cs, &cn);
74 if (cn > cs)
75 return r;
13e4a3f9
AW
76 }
77 }
838b33b4 78 //__enable_irq();
df27a6a3 79 return 0;
4cff3ded 80}
e6b5ae25 81
adc927a8
MM
82int Gcode::get_int( char letter )
83{
105d8d3e
MM
84 const char* cs = command.c_str();
85 char* cn = NULL;
86 for (; *cs; cs++){
87 if( letter == *cs ){
88 cs++;
89 int r = strtol(cs, &cn, 10);
90 if (cn > cs)
91 return r;
adc927a8
MM
92 }
93 }
94 return 0;
95}
96
d8f8bbf3
L
97int Gcode::get_num_args(){
98 int count = 0;
99 for(size_t i=1; i<this->command.length(); i++){
100 if( this->command.at(i) >= 'A' && this->command.at(i) <= 'Z' ){
101 count++;
102 }
103 }
104 return count;
105}
106
edac9072 107// Cache some of this command's properties, so we don't have to parse the string every time we want to look at them
e6b5ae25
AW
108void Gcode::prepare_cached_values(){
109 if( this->has_letter('G') ){
110 this->has_g = true;
105d8d3e 111 this->g = this->get_int('G');
e6b5ae25
AW
112 }else{
113 this->has_g = false;
114 }
115 if( this->has_letter('M') ){
116 this->has_m = true;
105d8d3e 117 this->m = this->get_int('M');
e6b5ae25
AW
118 }else{
119 this->has_m = false;
120 }
121}
74b6303c
DD
122
123void Gcode::mark_as_taken(){
124 this->accepted_by_module = true;
125}