Stan  2.5.0
probability, sampling & optimization
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
stanc_helper.hpp
Go to the documentation of this file.
1 #include <stan/version.hpp>
2 #include <stan/gm/compiler.hpp>
3 
4 #include <exception>
5 #include <fstream>
6 #include <iostream>
7 #include <stdexcept>
8 #include <string>
9 
10 #include <stan/io/cmd_line.hpp>
11 
12 void print_version(std::ostream* out_stream) {
13  if (!out_stream) return;
14  *out_stream << "stanc version "
16  << "."
18  << "."
20  << std::endl;
21 }
22 
26 void print_stanc_help(std::ostream* out_stream) {
28 
29  if (!out_stream) return;
30 
31  *out_stream << std::endl;
32  print_version(out_stream);
33  *out_stream << std::endl;
34 
35  *out_stream << "USAGE: " << "stanc [options] <model_file>" << std::endl;
36  *out_stream << std::endl;
37 
38  *out_stream << "OPTIONS:" << std::endl;
39  *out_stream << std::endl;
40 
41  print_help_option(out_stream,"help","","Display this information");
42 
43  print_help_option(out_stream,"version","","Display stanc version number");
44 
45  print_help_option(out_stream,"name","string",
46  "Model name",
47  "default = \"$model_filename_model\"");
48 
49  print_help_option(out_stream,"o","file",
50  "Output file for generated C++ code",
51  "default = \"$name.cpp\"");
52 
53 }
54 
55 void delete_file(std::ostream* err_stream,
56  const std::string& file_name) {
57  int deleted = std::remove(file_name.c_str());
58  if (deleted != 0 && file_name.size() > 0)
59  if (err_stream)
60  std::cerr << "Could not remove output file=" << file_name
61  << std::endl;
62 }
63 
64 
65 int stanc_helper(int argc, const char* argv[],
66  std::ostream* out_stream, std::ostream* err_stream) {
67  static const int SUCCESS_RC = 0;
68  static const int EXCEPTION_RC = -1;
69  static const int PARSE_FAIL_RC = -2;
70  static const int INVALID_ARGUMENT_RC = -3;
71 
72  std::string out_file_name; // declare outside of try to delete in catch
73 
74  try {
75 
76  stan::io::cmd_line cmd(argc,argv);
77 
78  if (cmd.has_flag("help")) {
79  print_stanc_help(out_stream);
80  return SUCCESS_RC;
81  }
82 
83  if (cmd.has_flag("version")) {
84  print_version(out_stream);
85  return SUCCESS_RC;
86  }
87 
88  if (cmd.bare_size() != 1) {
89  std::string msg("Require model file as argument. ");
90  throw std::invalid_argument(msg);
91  }
92  std::string in_file_name;
93  cmd.bare(0,in_file_name);
94  std::fstream in(in_file_name.c_str());
95 
96  std::string model_name;
97  if (cmd.has_key("name")) {
98  cmd.val("name",model_name);
99  } else {
100  size_t slashInd = in_file_name.rfind('/');
101  size_t ptInd = in_file_name.rfind('.');
102  if (ptInd == std::string::npos)
103  ptInd = in_file_name.length();
104  if (slashInd == std::string::npos) {
105  slashInd = in_file_name.rfind('\\');
106  }
107  if (slashInd == std::string::npos) {
108  slashInd = 0;
109  } else {
110  slashInd++;
111  }
112  model_name = in_file_name.substr(slashInd,ptInd - slashInd) + "_model";
113  for (std::string::iterator strIt = model_name.begin();
114  strIt != model_name.end(); strIt++) {
115  if (!isalnum(*strIt) && *strIt != '_') {
116  *strIt = '_';
117  }
118  }
119  }
120 
121  if (cmd.has_key("o")) {
122  cmd.val("o",out_file_name);
123  } else {
124  out_file_name = model_name;
125  out_file_name += ".cpp";
126  }
127 
128  if (!isalpha(model_name[0]) && model_name[0] != '_') {
129  std::string msg("model_name must not start with a number or symbol other than _");
130  throw std::invalid_argument(msg);
131  }
132  for (std::string::iterator strIt = model_name.begin();
133  strIt != model_name.end(); strIt++) {
134  if (!isalnum(*strIt) && *strIt != '_') {
135  std::string msg("model_name must contain only letters, numbers and _");
136  throw std::invalid_argument(msg);
137  }
138  }
139 
140  stan::gm::program prog;
141  std::fstream out(out_file_name.c_str(),
142  std::fstream::out);
143  if (out_stream) {
144  *out_stream << "Model name=" << model_name << std::endl;
145  *out_stream << "Input file=" << in_file_name << std::endl;
146  *out_stream << "Output file=" << out_file_name << std::endl;
147  }
148  bool valid_model
149  = stan::gm::compile(err_stream,in,out,model_name,in_file_name);
150  out.close();
151  if (!valid_model) {
152  if (err_stream)
153  *err_stream << "PARSING FAILED." << std::endl;
154  delete_file(out_stream,out_file_name); // FIXME: how to remove triple cut-and-paste?
155  return PARSE_FAIL_RC;
156  }
157  } catch (const std::invalid_argument& e) {
158  if (err_stream) {
159  *err_stream << std::endl
160  << e.what()
161  << std::endl;
162  *err_stream << "Execute \"stanc --help\" for more information"
163  << std::endl;
164  delete_file(out_stream,out_file_name);
165  }
166  return INVALID_ARGUMENT_RC;
167  } catch (const std::exception& e) {
168  if (err_stream) {
169  *err_stream << std::endl
170  << e.what()
171  << std::endl;
172  }
173  delete_file(out_stream,out_file_name);
174  return EXCEPTION_RC;
175  }
176 
177  return SUCCESS_RC;
178 }
179 
bool val(const std::string &key, T &x) const
Returns the value for the key provided.
Definition: cmd_line.hpp:189
void delete_file(std::ostream *err_stream, const std::string &file_name)
bool has_key(const std::string &key) const
Return true if the specified key is defined.
Definition: cmd_line.hpp:165
Parses and stores command-line arguments.
Definition: cmd_line.hpp:113
void print_version(std::ostream *out_stream)
int stanc_helper(int argc, const char *argv[], std::ostream *out_stream, std::ostream *err_stream)
bool has_flag(const std::string &flag) const
Return true if the specified flag is defined.
Definition: cmd_line.hpp:203
const std::string MINOR_VERSION
Minor version number for Stan package.
Definition: version.hpp:12
size_t bare_size() const
Return the number of bare arguments.
Definition: cmd_line.hpp:212
const std::string PATCH_VERSION
Patch version for Stan package.
Definition: version.hpp:15
double e()
Return the base of the natural logarithm.
Definition: constants.hpp:86
void print_stanc_help(std::ostream *out_stream)
Prints the Stan compiler (stanc) help.
bool bare(size_t n, T &x) const
Returns the bare argument.
Definition: cmd_line.hpp:230
void print_help_option(std::ostream *o, const std::string &key, const std::string &value_type, const std::string &msg, const std::string &note="")
Prints single print option to output ptr if non-null.
Definition: cmd_line.hpp:74
const std::string MAJOR_VERSION
Major version number for Stan package.
Definition: version.hpp:9
bool compile(std::ostream *msgs, std::istream &stan_gm_in, std::ostream &cpp_out, const std::string &model_name, const std::string &in_file_name="input")
Read a Stan model specification from the specified input, parse it, and write the C++ code for it to ...
Definition: compiler.hpp:37

     [ Stan Home Page ] © 2011–2014, Stan Development Team.