Gcode: simplify get_int, use get_int to derive cached M and G codes
[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
8b8b3339 17
6a3328df 18Gcode::Gcode(const string& command, StreamOutput* stream) :
c63ba1a4
BG
19 command(command), m(0), g(0), add_nl(false),
20 queued(0), stream(stream)
702023f3 21{
702023f3
MM
22 prepare_cached_values();
23}
4cff3ded 24
2bb8b390 25// Whether or not a Gcode has a letter
4cff3ded 26bool Gcode::has_letter( char letter ){
13e4a3f9 27 //return ( this->command->find( letter ) != string::npos );
f36ddd7d
BG
28 for (std::string::const_iterator c = this->command.cbegin(); c != this->command.cend(); c++) {
29 if( *c == letter ){
13e4a3f9
AW
30 return true;
31 }
32 }
33 return false;
4cff3ded
AW
34}
35
13e4a3f9
AW
36// Retrieve the value for a given letter
37// 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 38double Gcode::get_value( char letter ){
838b33b4 39 //__disable_irq();
cf67ed1b
MM
40 const char* cs = command.c_str();
41 char* cn = NULL;
42 for (; *cs; cs++){
43 if( letter == *cs ){
44 cs++;
45 double r = strtod(cs, &cn);
46 if (cn > cs)
47 return r;
13e4a3f9
AW
48 }
49 }
838b33b4 50 //__enable_irq();
df27a6a3 51 return 0;
4cff3ded 52}
e6b5ae25 53
adc927a8
MM
54int Gcode::get_int( char letter )
55{
105d8d3e
MM
56 const char* cs = command.c_str();
57 char* cn = NULL;
58 for (; *cs; cs++){
59 if( letter == *cs ){
60 cs++;
61 int r = strtol(cs, &cn, 10);
62 if (cn > cs)
63 return r;
adc927a8
MM
64 }
65 }
66 return 0;
67}
68
d8f8bbf3
L
69int Gcode::get_num_args(){
70 int count = 0;
71 for(size_t i=1; i<this->command.length(); i++){
72 if( this->command.at(i) >= 'A' && this->command.at(i) <= 'Z' ){
73 count++;
74 }
75 }
76 return count;
77}
78
e6b5ae25
AW
79void Gcode::prepare_cached_values(){
80 if( this->has_letter('G') ){
81 this->has_g = true;
105d8d3e 82 this->g = this->get_int('G');
e6b5ae25
AW
83 }else{
84 this->has_g = false;
85 }
86 if( this->has_letter('M') ){
87 this->has_m = true;
105d8d3e 88 this->m = this->get_int('M');
e6b5ae25
AW
89 }else{
90 this->has_m = false;
91 }
92}