-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
131 lines (98 loc) · 2.68 KB
/
main.cpp
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
// main.cpp
//
// ICS 45C Spring 2022
// Project #4: People Just Love to Play with Words
//
// This is the main() function that launches BooEdit, along with some
// additional things that are fairly hairy-looking. The goal here is
// to be sure that the program, whenever possible, crashes in a way that
// leaves the Linux shell window available and fully operative afterward.
// For example, I'm calling into functions from the C Standard Library
// that set up "signal handlers" that are called just before the program
// crashes due to problems like segmentation faults, so I can shut down
// the "ncurses" library used to handle things like cursor manipulation,
// and return the Linux shell to a usable state.
//
// DO NOT MAKE CHANGES TO THIS FILE
#include <csignal>
#include <sstream>
#include "BooEdit.hpp"
#include "BooEditLog.hpp"
#include "EditorModel.hpp"
#include "KeypressInteractionReader.hpp"
#include "NcursesEditorView.hpp"
#include "NcursesKeypressReader.hpp"
namespace
{
BooEdit* booEdit = nullptr;
EditorModel model;
NcursesEditorView view{model};
NcursesKeypressReader keypressReader;
KeypressInteractionReader interactionReader{keypressReader};
void logStarted(const std::string& programName)
{
std::ostringstream oss;
oss << "Started " << programName;
booEditLog(oss.str());
}
void logStopped(const std::string& programName)
{
std::ostringstream oss;
oss << "Stopped " << programName;
booEditLog(oss.str());
}
void startBooEdit()
{
booEdit = new BooEdit{model, view, interactionReader};
booEdit->run();
}
void stopBooEdit()
{
if (booEdit != nullptr)
{
delete booEdit;
booEdit = nullptr;
}
}
int signals[6] { SIGTERM, SIGSEGV, SIGILL, SIGINT, SIGABRT, SIGFPE };
void unregisterSignalHandlers()
{
for (int signal : signals)
{
std::signal(signal, SIG_DFL);
}
}
void signalHandler(int signum)
{
unregisterSignalHandlers();
stopBooEdit();
}
void registerSignalHandlers()
{
for (int signal : signals)
{
std::signal(signal, signalHandler);
}
}
}
int main(int argc, char** argv)
{
std::string programName{argv[0]};
try
{
logStarted(programName);
registerSignalHandlers();
startBooEdit();
unregisterSignalHandlers();
stopBooEdit();
logStopped(programName);
}
catch (...)
{
unregisterSignalHandlers();
stopBooEdit();
logStopped(programName);
throw;
}
return 0;
}