souffle  2.0.2-371-g6315b36
CompiledOptions.h
Go to the documentation of this file.
1 /*
2  * Souffle - A Datalog Compiler
3  * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved
4  * Licensed under the Universal Permissive License v 1.0 as shown at:
5  * - https://opensource.org/licenses/UPL
6  * - <souffle root>/licenses/SOUFFLE-UPL.txt
7  */
8 
9 /************************************************************************
10  *
11  * @file CompiledOptions.h
12  *
13  * A header file offering command-line option support for compiled
14  * RAM programs.
15  *
16  ***********************************************************************/
17 
18 #pragma once
19 
20 #include <cstdio>
21 #include <cstdlib>
22 #include <iostream>
23 #include <string>
24 #include <getopt.h>
25 #include <sys/stat.h>
26 
27 namespace souffle {
28 
29 /**
30  * A utility class for parsing command line arguments within generated
31  * query programs.
32  */
33 class CmdOptions {
34 protected:
35  /**
36  * source file
37  */
38  std::string src;
39 
40  /**
41  * fact directory
42  */
43  std::string input_dir;
44 
45  /**
46  * output directory
47  */
48  std::string output_dir;
49 
50  /**
51  * profiling flag
52  */
53  bool profiling;
54 
55  /**
56  * profile filename
57  */
58  std::string profile_name;
59 
60  /**
61  * number of threads
62  */
63  size_t num_jobs;
64 
65 public:
66  // all argument constructor
67  CmdOptions(const char* s, const char* id, const char* od, bool pe, const char* pfn, size_t nj)
68  : src(s), input_dir(id), output_dir(od), profiling(pe), profile_name(pfn), num_jobs(nj) {}
69 
70  /**
71  * get source code name
72  */
73  const std::string& getSourceFileName() const {
74  return src;
75  }
76 
77  /**
78  * get input directory
79  */
80  const std::string& getInputFileDir() const {
81  return input_dir;
82  }
83 
84  /**
85  * get output directory
86  */
87  const std::string& getOutputFileDir() const {
88  return output_dir;
89  }
90 
91  /**
92  * is profiling switched on
93  */
94  bool isProfiling() const {
95  return profiling;
96  }
97 
98  /**
99  * get filename of profile
100  */
101  const std::string& getProfileName() const {
102  return profile_name;
103  }
104 
105  /**
106  * get number of jobs
107  */
108  size_t getNumJobs() const {
109  return num_jobs;
110  }
111 
112  /**
113  * Parses the given command line parameters, handles -h help requests or errors
114  * and returns whether the parsing was successful or not.
115  */
116  bool parse(int argc, char** argv) {
117  // get executable name
118  std::string exec_name = "analysis";
119  if (argc > 0) {
120  exec_name = argv[0];
121  }
122 
123  // local options
124  std::string fact_dir = input_dir;
125  std::string out_dir = output_dir;
126 
127  // long options
128  option longOptions[] = {{"facts", true, nullptr, 'F'}, {"output", true, nullptr, 'D'},
129  {"profile", true, nullptr, 'p'}, {"jobs", true, nullptr, 'j'}, {"index", true, nullptr, 'i'},
130  // the terminal option -- needs to be null
131  {nullptr, false, nullptr, 0}};
132 
133  // check whether all options are fine
134  bool ok = true;
135 
136  int c; /* command-line arguments processing */
137  while ((c = getopt_long(argc, argv, "D:F:hp:j:i:", longOptions, nullptr)) != EOF) {
138  switch (c) {
139  /* Fact directories */
140  case 'F':
141  if (!existDir(optarg)) {
142  printf("Fact directory %s does not exists!\n", optarg);
143  ok = false;
144  }
145  fact_dir = optarg;
146  break;
147  /* Output directory for resulting .csv files */
148  case 'D':
149  if (*optarg && !existDir(optarg)) {
150  printf("Output directory %s does not exists!\n", optarg);
151  ok = false;
152  }
153  out_dir = optarg;
154  break;
155  case 'p':
156  if (!profiling) {
157  std::cerr << "\nError: profiling was not enabled in compilation\n\n";
158  printHelpPage(exec_name);
159  exit(EXIT_FAILURE);
160  }
161  profile_name = optarg;
162  break;
163  case 'j':
164 #ifdef _OPENMP
165  if (std::string(optarg) == "auto") {
166  num_jobs = 0;
167  } else {
168  int num = atoi(optarg);
169  if (num > 0) {
170  num_jobs = num;
171  } else {
172  std::cerr << "Invalid number of jobs [-j]: " << optarg << "\n";
173  ok = false;
174  }
175  }
176 #else
177  std::cerr << "\nWarning: OpenMP was not enabled in compilation\n\n";
178 #endif
179  break;
180  default: printHelpPage(exec_name); return false;
181  }
182  }
183 
184  // update member fields
185  input_dir = fact_dir;
186  output_dir = out_dir;
187 
188  // return success state
189  return ok;
190  }
191 
192 private:
193  /**
194  * Prints the help page if it has been requested or there was a typo in the command line arguments.
195  */
196  void printHelpPage(const std::string& exec_name) const {
197  std::cerr << "====================================================================\n";
198  std::cerr << " Datalog Program: " << src << "\n";
199  std::cerr << " Usage: " << exec_name << " [OPTION]\n\n";
200  std::cerr << " Options:\n";
201  std::cerr << " -D <DIR>, --output=<DIR> -- Specify directory for output relations\n";
202  std::cerr << " (default: " << output_dir << ")\n";
203  std::cerr << " (suppress output with \"\")\n";
204  std::cerr << " -F <DIR>, --facts=<DIR> -- Specify directory for fact files\n";
205  std::cerr << " (default: " << input_dir << ")\n";
206  if (profiling) {
207  std::cerr << " -p <file>, --profile=<file> -- Specify filename for profiling\n";
208  std::cerr << " (default: " << profile_name << ")\n";
209  }
210 #ifdef _OPENMP
211  std::cerr << " -j <NUM>, --jobs=<NUM> -- Specify number of threads\n";
212  if (num_jobs > 0) {
213  std::cerr << " (default: " << num_jobs << ")\n";
214  } else {
215  std::cerr << " (default: auto)\n";
216  }
217 #endif
218  std::cerr << " -h -- prints this help page.\n";
219  std::cerr << "--------------------------------------------------------------------\n";
220  std::cout << " Copyright (c) 2016-20 The Souffle Developers." << std::endl;
221  std::cout << " Copyright (c) 2013-16 Oracle and/or its affiliates." << std::endl;
222  std::cerr << " All rights reserved.\n";
223  std::cerr << "====================================================================\n";
224  }
225 
226  /**
227  * Check whether a file exists in the file system
228  */
229  inline bool existFile(const std::string& name) const {
230  struct stat buffer;
231  if (stat(name.c_str(), &buffer) == 0) {
232  if ((buffer.st_mode & S_IFREG) != 0) {
233  return true;
234  }
235  }
236  return false;
237  }
238 
239  /**
240  * Check whether a directory exists in the file system
241  */
242  bool existDir(const std::string& name) const {
243  struct stat buffer;
244  if (stat(name.c_str(), &buffer) == 0) {
245  if ((buffer.st_mode & S_IFDIR) != 0) {
246  return true;
247  }
248  }
249  return false;
250  }
251 };
252 
253 } // end of namespace souffle
tinyformat::printf
void printf(const char *fmt)
Definition: tinyformat.h:1101
souffle::id
A functor representing the identity function for a generic type T.
Definition: StreamUtil.h:136
souffle::CmdOptions::getNumJobs
size_t getNumJobs() const
get number of jobs
Definition: CompiledOptions.h:122
souffle::CmdOptions::existFile
bool existFile(const std::string &name) const
Check whether a file exists in the file system.
Definition: CompiledOptions.h:243
souffle::CmdOptions::parse
bool parse(int argc, char **argv)
Parses the given command line parameters, handles -h help requests or errors and returns whether the ...
Definition: CompiledOptions.h:130
souffle::CmdOptions::profile_name
std::string profile_name
profile filename
Definition: CompiledOptions.h:72
souffle::CmdOptions::getProfileName
const std::string & getProfileName() const
get filename of profile
Definition: CompiledOptions.h:115
souffle::CmdOptions::num_jobs
size_t num_jobs
number of threads
Definition: CompiledOptions.h:77
souffle::CmdOptions::getInputFileDir
const std::string & getInputFileDir() const
get input directory
Definition: CompiledOptions.h:94
souffle::CmdOptions::src
std::string src
source file
Definition: CompiledOptions.h:52
souffle::CmdOptions::getSourceFileName
const std::string & getSourceFileName() const
get source code name
Definition: CompiledOptions.h:87
souffle::CmdOptions::output_dir
std::string output_dir
output directory
Definition: CompiledOptions.h:62
souffle::CmdOptions::profiling
bool profiling
profiling flag
Definition: CompiledOptions.h:67
souffle::CmdOptions::input_dir
std::string input_dir
fact directory
Definition: CompiledOptions.h:57
souffle::CmdOptions::getOutputFileDir
const std::string & getOutputFileDir() const
get output directory
Definition: CompiledOptions.h:101
souffle::CmdOptions::existDir
bool existDir(const std::string &name) const
Check whether a directory exists in the file system.
Definition: CompiledOptions.h:256
souffle
Definition: AggregateOp.h:25
souffle::CmdOptions::printHelpPage
void printHelpPage(const std::string &exec_name) const
Prints the help page if it has been requested or there was a typo in the command line arguments.
Definition: CompiledOptions.h:210
souffle::CmdOptions::isProfiling
bool isProfiling() const
is profiling switched on
Definition: CompiledOptions.h:108
souffle::CmdOptions::CmdOptions
CmdOptions(const char *s, const char *id, const char *od, bool pe, const char *pfn, size_t nj)
Definition: CompiledOptions.h:81