mirror of
https://github.com/louisrubet/rpn
synced 2025-02-11 20:48:30 +01:00
Simplify history management
This commit is contained in:
parent
29c839c873
commit
39c9a75c7e
1 changed files with 21 additions and 47 deletions
68
src/main.cc
68
src/main.cc
|
@ -12,9 +12,21 @@ using std::cerr;
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "program.h"
|
#include "program.h"
|
||||||
|
|
||||||
/// @brief actions to be done at rpn exit
|
/// @brief lines history management: load file
|
||||||
///
|
///
|
||||||
static void ExitInteractive() {
|
static void StartHistory() {
|
||||||
|
struct passwd* pw = getpwuid(getuid());
|
||||||
|
if (pw != nullptr) {
|
||||||
|
stringstream history_path;
|
||||||
|
history_path << pw->pw_dir << "/.rpn_history";
|
||||||
|
linenoiseHistorySetMaxLen(100);
|
||||||
|
linenoiseHistoryLoad(history_path.str().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief lines history management: save
|
||||||
|
///
|
||||||
|
static void StopHistory() {
|
||||||
struct passwd* pw = getpwuid(getuid());
|
struct passwd* pw = getpwuid(getuid());
|
||||||
if (pw != nullptr) {
|
if (pw != nullptr) {
|
||||||
stringstream history_path;
|
stringstream history_path;
|
||||||
|
@ -24,7 +36,6 @@ static void ExitInteractive() {
|
||||||
ofstream history(history_path.str(), ios_base::out | ios_base::trunc);
|
ofstream history(history_path.str(), ios_base::out | ios_base::trunc);
|
||||||
history.close();
|
history.close();
|
||||||
|
|
||||||
// save it
|
|
||||||
if (linenoiseHistorySave(history_path.str().c_str()) != 0)
|
if (linenoiseHistorySave(history_path.str().c_str()) != 0)
|
||||||
cerr << "warning, could not save " << history_path.str() << " [errno=" << errno << ' ' << strerror(errno)
|
cerr << "warning, could not save " << history_path.str() << " [errno=" << errno << ' ' << strerror(errno)
|
||||||
<< "']" << endl;
|
<< "']" << endl;
|
||||||
|
@ -32,38 +43,13 @@ static void ExitInteractive() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief actions to be done at rpn exit
|
|
||||||
///
|
|
||||||
static void EnterInteractive() {
|
|
||||||
struct passwd* pw = getpwuid(getuid());
|
|
||||||
if (pw != nullptr) {
|
|
||||||
stringstream history_path;
|
|
||||||
history_path << pw->pw_dir << "/.rpn_history";
|
|
||||||
|
|
||||||
// don't care about errors
|
|
||||||
linenoiseHistorySetMaxLen(100);
|
|
||||||
linenoiseHistoryLoad(history_path.str().c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief handle CtrlC signal (sigaction handler): exit rpn
|
|
||||||
///
|
|
||||||
/// @param sig signal, see POSIX sigaction
|
|
||||||
/// @param siginfo signal info, see POSIX sigaction
|
|
||||||
/// @param context see POSIX sigaction
|
|
||||||
///
|
|
||||||
static void CtrlHandler(int sig __attribute__((unused)), siginfo_t* siginfo __attribute__((unused)),
|
static void CtrlHandler(int sig __attribute__((unused)), siginfo_t* siginfo __attribute__((unused)),
|
||||||
void* context __attribute__((unused))) {
|
void* context __attribute__((unused))) {
|
||||||
ExitInteractive();
|
StopHistory(); // don't put an entry line canceled with CtrlC in history
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief setup signals handlers to stop with honours
|
static void CatchCtrlC() {
|
||||||
///
|
|
||||||
/// @param prog the prog to catch the signals to, must be checked not nullptr by user
|
|
||||||
///
|
|
||||||
static void CatchSignals() {
|
|
||||||
struct sigaction act = {0};
|
struct sigaction act = {0};
|
||||||
|
|
||||||
act.sa_sigaction = &CtrlHandler;
|
act.sa_sigaction = &CtrlHandler;
|
||||||
act.sa_flags = SA_SIGINFO;
|
act.sa_flags = SA_SIGINFO;
|
||||||
if (sigaction(SIGINT, &act, nullptr) < 0)
|
if (sigaction(SIGINT, &act, nullptr) < 0)
|
||||||
|
@ -87,23 +73,16 @@ int main(int argc, char* argv[]) {
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
Program::Welcome();
|
Program::Welcome();
|
||||||
|
|
||||||
// init history
|
StartHistory();
|
||||||
EnterInteractive();
|
CatchCtrlC();
|
||||||
|
|
||||||
// user could stop prog with CtrlC
|
|
||||||
CatchSignals();
|
|
||||||
|
|
||||||
// entry loop
|
|
||||||
heap heap;
|
heap heap;
|
||||||
rpnstack stack;
|
rpnstack stack;
|
||||||
while (go_on) {
|
while (go_on) {
|
||||||
//
|
|
||||||
// make program from interactive entry
|
|
||||||
Program prog(stack, heap);
|
Program prog(stack, heap);
|
||||||
string entry;
|
string entry;
|
||||||
switch (Input(entry, Program::GetAutocompletionWords()).status) {
|
switch (Input(entry, Program::GetAutocompletionWords()).status) {
|
||||||
case Input::InputStatus::kOk:
|
case Input::InputStatus::kOk:
|
||||||
// run it
|
|
||||||
if (prog.Parse(entry) == kOk && prog.Run() == kGoodbye)
|
if (prog.Parse(entry) == kOk && prog.Run() == kGoodbye)
|
||||||
go_on = false;
|
go_on = false;
|
||||||
else
|
else
|
||||||
|
@ -116,10 +95,9 @@ int main(int argc, char* argv[]) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
StopHistory();
|
||||||
// manage history and exit
|
} else {
|
||||||
ExitInteractive();
|
// run with cmd line arguments
|
||||||
} else { // run with cmd line arguments
|
|
||||||
heap heap;
|
heap heap;
|
||||||
rpnstack stack;
|
rpnstack stack;
|
||||||
Program prog(stack, heap);
|
Program prog(stack, heap);
|
||||||
|
@ -132,10 +110,6 @@ int main(int argc, char* argv[]) {
|
||||||
// make program
|
// make program
|
||||||
ret = prog.Parse(entry);
|
ret = prog.Parse(entry);
|
||||||
if (ret == kOk) {
|
if (ret == kOk) {
|
||||||
// user could stop prog with CtrlC
|
|
||||||
CatchSignals();
|
|
||||||
|
|
||||||
// run it
|
|
||||||
ret = prog.Run();
|
ret = prog.Run();
|
||||||
prog.ShowStack(false);
|
prog.ShowStack(false);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue