MinitScript  0.9.31 PRE-BETA
minitscript-main.cpp
Go to the documentation of this file.
1 #include <cstdlib>
2 #include <cstdio>
3 #include <iostream>
4 #include <memory>
5 #include <string>
6 
7 // Windows MSC: required for OpenSSL to work when having OpenSSL embedded in a DLL which is used here
8 #if defined(_MSC_VER)
9  #include <openssl/applink.c>
10 #endif
11 
21 
22 using std::cin;
23 using std::exit;
24 using std::make_unique;
25 using std::string;
26 using std::tmpnam;
27 using std::unique_ptr;
28 
37 
38 int main(int argc, char** argv)
39 {
40  //
41  auto printVersion = [&]() -> void {
42  Console::printLine(string("minitscript ") + Version::getVersion());
43  Console::printLine(Version::getCopyright());
44  };
45  //
46  auto printUsage = [&]() -> void {
47  Console::printLine("Usage: minitscript [--version] [--verbose] [path_to_script | < path_to_script] --arguments [script command line arguments...]");
48  };
49  //
50  auto printInformation = [&]() -> void {
51  printVersion();
52  Console::printLine();
53  printUsage();
54  Console::printLine();
55  Console::printLine("If you do not provide a path to the script or do not pipe a script into the standard input stream,");
56  Console::printLine("you get a prompt to enter your script. You can finish inputting by hitting Ctrl-D on Unix or Ctrl-Z on Windows.");
57  };
58 
59  //
60  string pathToScript;
61  auto verbose = false;
62  auto version = false;
63  for (auto i = 1; i < argc; i++) {
64  string argument = argv[i];
65  if (argument == "--help") {
66  printInformation();
67  return EXIT_SUCCESS;
68  } else
69  if (argument == "--version") {
70  version = true;
71  } else
72  if (argument == "--verbose") {
73  verbose = true;
74  } else
75  if (argument == "--arguments") {
76  break;
77  } else {
78  if (pathToScript.empty() == false) {
79  Console::printLine("Invalid command line arguments!");
80  Console::printLine();
81  printUsage();
82  return EXIT_FAILURE;
83  } else {
84  pathToScript = argument;
85  }
86  }
87  }
88 
89  // version
90  if (version == true) {
91  printVersion();
92  return EXIT_FAILURE;
93  }
94 
95  //
96  MinitScript::initialize();
97  // run script
98  unique_ptr<Context> context;
99  unique_ptr<MinitScript> script;
100  // if no file given, then read from input stream until Ctrl+D(Unix) or Ctrl+Z(Windows) was hit
101  // which is the standard behaviour of those kind of CLI apps
102  // we store the file as temporary one and reuse it for execution
103  string tmpFile;
104  if (pathToScript.empty() == true) {
105  // read from standard input
106  auto statementsOnly = true;
107  string scriptCode;
108  string line;
109  while (cin.eof() == false && getline(cin, line)) {
110  if (StringTools::startsWith(line, "on:") == true ||
111  StringTools::startsWith(line, "on-enabled:") == true ||
112  StringTools::startsWith(line, "function:") == true ||
113  StringTools::startsWith(line, "callable:") == true) statementsOnly = false;
114  scriptCode+= line + "\n";
115  }
116  pathToScript = tmpnam(nullptr);
117  // create the script
118  try {
119  if (statementsOnly == true) {
120  scriptCode = StringTools::replace(
121  FileSystem::getContentAsString(MINITSCRIPT_DATA + "/resources/minitscript/templates/cli", "statements.tscript"),
122  "{$statements}",
123  scriptCode
124  );
125  }
126  //
127  FileSystem::setContentFromString(
128  FileSystem::getPathName(pathToScript),
129  FileSystem::getFileName(pathToScript),
130  scriptCode
131  );
132  // we want to delete the script later
133  tmpFile = pathToScript;
134  } catch (Exception& exception) {
135  pathToScript.clear();
136  Console::printLine("An error occurred: " + string(exception.what()));
137  }
138  }
139  // do we have a script to run?
140  if (pathToScript.empty() == false) {
141  // yes, go
142  context = make_unique<Context>();
143  //
144  {
145  // create main argument values
146  vector<string> argumentValues;
147  argumentValues.push_back(string(argv[0]));
148  bool haveArguments = false;
149  for (auto i = 0; i < argc; i++) {
150  string argumentValue(argv[i]);
151  if (haveArguments == false &&
152  argumentValue == "--arguments") {
153  haveArguments = true;
154  continue;
155  }
156  //
157  if (haveArguments == false) continue;
158  //
159  argumentValues.push_back(argumentValue);
160  }
161  //
162  context->setArgumentValues(argumentValues);
163  }
164 
165  script = make_unique<MinitScript>();
166  script->setContext(context.get());
167  script->parseScript(
168  FileSystem::getPathName(pathToScript),
169  FileSystem::getFileName(pathToScript)
170  );
171  //
172  if (script != nullptr) {
173  // verbose
174  if (verbose == true/* && script->isValid() == true*/) Console::printLine(script->getInformation());
175  //
176  if (script->isValid() == false) {
177  Console::printLine(pathToScript + ": Script not valid. Exiting!");
178  return EXIT_SUCCESS;
179  } else {
180  // TODO: we need a MinitScript startup routine
181  Network::initialize();
182  // Windows MSC: required for OpenSSL to work when having OpenSSL embedded in a DLL which is used here
183  #if defined(_MSC_VER)
184  OPENSSL_Applink();
185  #endif
186  // add script to context
187  auto scriptPtr = script.get();
188  context->push(scriptPtr);
189  context->addScript("application", script.release());
190  //
191  while (scriptPtr->isRunning() == true) {
192  scriptPtr->execute();
193  }
194  context->pop();
195  }
196  } else {
197  return EXIT_FAILURE;
198  }
199  } else
200  if (version == false) {
201  printInformation();
202  return EXIT_SUCCESS;
203  }
204 
205  // delete temporary file if we have created any
206  if (tmpFile.empty() == false) {
207  try {
208  FileSystem::removeFile(
209  FileSystem::getPathName(tmpFile),
210  FileSystem::getFileName(tmpFile)
211  );
212  } catch (Exception& exception) {
213  pathToScript.clear();
214  Console::printLine("An error occurred: " + string(exception.what()));
215  }
216  }
217 
218  //
219  return context->getExitCode();
220 }
int main(int argc, char **argv)
#define MINITSCRIPT_DATA
Definition: minitscript.h:22
std::exception Exception
Exception base class.
Definition: Exception.h:18