removed most mbed.h includes
[clinton/Smoothieware.git] / src / modules / utils / simpleshell / SimpleShell.cpp
CommitLineData
cd011f58
AW
1/*
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.
5 You should have received a copy of the GNU General Public License along with Smoothie. If not, see <http://www.gnu.org/licenses/>.
6*/
7
8
0325af12
AW
9#include "libs/Kernel.h"
10#include "SimpleShell.h"
11#include "libs/nuts_bolts.h"
12#include "libs/utils.h"
423df6df 13#include "libs/SerialMessage.h"
0325af12
AW
14
15
16void SimpleShell::on_module_loaded(){
17 this->current_path = "/";
423df6df 18 this->playing_file = false;
0325af12 19 this->register_for_event(ON_CONSOLE_LINE_RECEIVED);
423df6df 20 this->register_for_event(ON_MAIN_LOOP);
0325af12
AW
21}
22
23// When a new line is received, check if it is a command, and if it is, act upon it
24void SimpleShell::on_console_line_received( void* argument ){
b6c86164
AW
25 SerialMessage new_message = *static_cast<SerialMessage*>(argument);
26 string possible_command = new_message.message;
0325af12
AW
27
28 // We don't compare to a string but to a checksum of that string, this saves some space in flash memory
29 unsigned short check_sum = get_checksum( possible_command.substr(0,possible_command.find_first_of(" \r\n")) ); // todo: put this method somewhere more convenient
cc63083e 30
0325af12
AW
31 // Act depending on command
32 switch( check_sum ){
b6c86164
AW
33 case ls_command_checksum : this->ls_command( get_arguments(possible_command), new_message.stream ); break;
34 case cd_command_checksum : this->cd_command( get_arguments(possible_command), new_message.stream ); break;
35 case cat_command_checksum : this->cat_command( get_arguments(possible_command), new_message.stream ); break;
36 case play_command_checksum : this->play_command(get_arguments(possible_command), new_message.stream ); break;
0325af12
AW
37 }
38}
39
0325af12
AW
40// Convert a path indication ( absolute or relative ) into a path ( absolute )
41string SimpleShell::absolute_from_relative( string path ){
42 if( path[0] == '/' ){ return path; }
43 if( path[0] == '.' ){ return this->current_path; }
44 return this->current_path + path;
45}
46
47// Act upon an ls command
48// Convert the first parameter into an absolute path, then list the files in that path
b6c86164 49void SimpleShell::ls_command( string parameters, Stream* stream ){
0325af12
AW
50 string folder = this->absolute_from_relative( parameters );
51 DIR* d;
52 struct dirent* p;
53 d = opendir(folder.c_str());
54 if(d != NULL) {
b6c86164 55 while((p = readdir(d)) != NULL) { stream->printf("%s\r\n", lc(string(p->d_name)).c_str()); }
0325af12 56 } else {
b6c86164 57 stream->printf("Could not open directory %s \r\n", folder.c_str());
0325af12
AW
58 }
59}
60
61// Change current absolute path to provided path
b6c86164 62void SimpleShell::cd_command( string parameters, Stream* stream ){
0325af12
AW
63 string folder = this->absolute_from_relative( parameters );
64 if( folder[folder.length()-1] != '/' ){ folder += "/"; }
65 DIR *d;
66 struct dirent *p;
67 d = opendir(folder.c_str());
68 if(d == NULL) {
b6c86164 69 stream->printf("Could not open directory %s \r\n", folder.c_str() );
0325af12
AW
70 }else{
71 this->current_path = folder;
72 }
73}
74
75// Output the contents of a file, first parameter is the filename, second is the limit ( in number of lines to output )
b6c86164 76void SimpleShell::cat_command( string parameters, Stream* stream ){
0325af12
AW
77
78 // Get parameters ( filename and line limit )
79 string filename = this->absolute_from_relative(shift_parameter( parameters ));
80 string limit_paramater = shift_parameter( parameters );
81 int limit = -1;
82 if( limit_paramater != "" ){ limit = int(atof(limit_paramater.c_str())); }
83
84 // Open file
85 FILE *lp = fopen(filename.c_str(), "r");
86 string buffer;
87 int c;
88 int newlines = 0;
89
90 // Print each line of the file
91 while ((c = fgetc (lp)) != EOF){
92 if( char(c) == '\n' ){ newlines++; }
b6c86164 93 stream->putc(c);
0325af12
AW
94 if( newlines == limit ){ break; }
95 };
96 fclose(lp);
97
98}
99
cc63083e 100// Play a gcode file by considering each line as if it was received on the serial console
b6c86164 101void SimpleShell::play_command( string parameters, Stream* stream ){
cc63083e 102 // Get filename
423df6df
AW
103 this->current_file_handler = fopen( this->absolute_from_relative(shift_parameter( parameters )).c_str(), "r");
104 this->playing_file = true;
105 this->current_stream = stream;
106}
107void SimpleShell::on_main_loop(void* argument){
108
109 if( this->playing_file ){
110 string buffer;
111 int c;
112 // Print each line of the file
113 while ((c = fgetc(this->current_file_handler)) != EOF){
114 if (c == '\n'){
115 this->current_stream->printf("%s\n", buffer.c_str());
116 struct SerialMessage message;
117 message.message = buffer;
118 message.stream = this->current_stream;
119 this->kernel->call_event(ON_CONSOLE_LINE_RECEIVED, &message);
120 buffer.clear();
121 return;
122 }else{
123 buffer += c;
124 }
125 };
126
127 fclose(this->current_file_handler);
128 this->playing_file = false;
129 }
2bb8b390 130}