-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathgareplxx.cpp
More file actions
150 lines (120 loc) · 3.73 KB
/
gareplxx.cpp
File metadata and controls
150 lines (120 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "gareplxx.h"
#include "goodasm.h"
#include <fstream>
#include <iostream>
#include <QDebug>
int gareplxx_encode(GoodASM *goodasm){
GAReplXX rxx{goodasm, ".goodasm_history" };
rxx.start();
return 0;
}
static bool isbytes(QString s){
int count=0;
s+=" ";
for(int i=0; i<s.length(); i++){
QChar c=s[i].toLower();
if(
!c.isDigit() &&
!c.isSpace() &&
!(c.toLatin1()>='a' && c.toLatin1()<='f')
){
return false;
}else if(c.isSpace()){
if((count&1)==1)
return false;
count=0;
}else{
//Count the next letter.
count++;
}
}
//All characters are spaces, numbers, or A through F.
//And nybbles are in pairs.
return true;
}
GAReplXX::GAReplXX(GoodASM *goodasm, const std::string& historyFile)
: historyFile(historyFile) {
this->goodasm=goodasm;
// Set non-default replxx preferences
using namespace std::placeholders;
set_completion_callback(std::bind(&GAReplXX::CompleteContext, this, _1, _2));
/*
set_completion_count_cutoff(128);
set_hint_callback(std::bind(&GAReplXX::Hint, this, _1, _2, _3));
set_indent_multiline(false);
set_max_history_size(1000);
set_prompt(this->prompt);
set_word_break_characters(Ifs);
*/
// Add handler for window size changes
install_window_change_handler();
// load the history file if it exists
if (!this->historyFile.empty()) {
std::ifstream fileStream{ historyFile.c_str() };
history_load(fileStream);
}
history_add(""); // Added to fix issue #137
}
void GAReplXX::start() {
//Lab mode by default.
goodasm->listadr=true;
if(!goodasm->listbits)
goodasm->listbytes=true;
int i=0;
do {
this->prompt=goodasm->lang->name.toStdString()+"> ";
// Prompt the user and get their input
const char* rawInput{ nullptr };
do {
rawInput = input(this->prompt);
} while ((rawInput == nullptr) && (errno == EAGAIN));
if (rawInput == nullptr) {
break;
}
std::string input{ rawInput };
if (input.empty()) {
// Handle a user hitting enter after an empty line
continue;
}
history_add(input);
QString line=QString(input.c_str());
if(!isbytes(line)){
goodasm->line=i;
goodasm->load(line);
}else{
QByteArray bytes=QByteArray::fromHex(line.toLocal8Bit());
goodasm->load(bytes);
}
std::cout<<goodasm->source().toStdString();
goodasm->printErrors();
goodasm->clear();
} while (true);
if (!this->historyFile.empty()) {
history_sync(this->historyFile);
}
}
replxx::Replxx::completions_t GAReplXX::CompleteContext(const std::string& line, int& lastWordLength) {
Replxx::completions_t completions;
for (auto& match : this->Matches(line)) {
completions.emplace_back(match.data(), Replxx::Color::DEFAULT);
}
return completions;
}
std::vector<std::string> GAReplXX::Matches(const std::string& line) {
std::vector<std::string> matches;
/*
std::string firstWord{ line.substr(0, WordBoundary(line.data())) };
if (firstWord.length() == line.length()) {
// Gather completions for a command
for (auto const& command : this->commands) {
auto& name{ command.first };
if (Equal(name, firstWord, firstWord.length())) {
matches.emplace_back(name.data());
}
}
}*/
foreach (auto c, goodasm->completions(QString(line.c_str()))) {
matches.emplace_back(c.toStdString());
}
return matches;
}