Stan  1.0
probability, sampling & optimization
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 include_main = !cmd.has_flag("no_main");
149  bool valid_model
150  = stan::gm::compile(err_stream,in,out,model_name,include_main,in_file_name);
151  out.close();
152  if (!valid_model) {
153  if (err_stream)
154  *err_stream << "PARSING FAILED." << std::endl;
155  delete_file(out_stream,out_file_name); // FIXME: how to remove triple cut-and-paste?
156  return PARSE_FAIL_RC;
157  }
158  } catch (const std::invalid_argument& e) {
159  if (err_stream) {
160  *err_stream << std::endl
161  << "INVALID COMMAND-LINE ARGUMENT"
162  << std::endl
163  << e.what()
164  << std::endl;
165  *err_stream << "Execute \"stanc --help\" for more information"
166  << std::endl;
167  delete_file(out_stream,out_file_name);
168  }
169  return INVALID_ARGUMENT_RC;
170  } catch (const std::exception& e) {
171  if (err_stream) {
172  *err_stream << std::endl
173  << "ERROR PARSING"
174  << std::endl
175  << e.what()
176  << std::endl;
177  }
178  delete_file(out_stream,out_file_name);
179  return EXCEPTION_RC;
180  }
181 
182  return SUCCESS_RC;
183 }
184 
Parses and stores command-line arguments.
Definition: cmd_line.hpp:111
size_t bare_size() const
Return the number of bare arguments.
Definition: cmd_line.hpp:210
bool has_key(const std::string &key) const
Return true if the specified key is defined.
Definition: cmd_line.hpp:163
bool has_flag(const std::string &flag) const
Return true if the specified flag is defined.
Definition: cmd_line.hpp:201
bool val(const std::string &key, T &x) const
Returns the value for the key provided.
Definition: cmd_line.hpp:187
bool bare(size_t n, T &x) const
Returns the bare argument.
Definition: cmd_line.hpp:228
bool compile(std::ostream *output_stream, std::istream &stan_gm_in, std::ostream &cpp_out, const std::string &model_name, bool include_main=true, const std::string &in_file_name="input")
Read a Stan directed graphical model specification from the specified input, parse it,...
Definition: compiler.hpp:31
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:72
double e()
Return the base of the natural logarithm.
const std::string MAJOR_VERSION
Major version number for Stan package.
Definition: version.hpp:9
const std::string MINOR_VERSION
Minor version number for Stan package.
Definition: version.hpp:12
const std::string PATCH_VERSION
Patch version for Stan package.
Definition: version.hpp:15
void delete_file(std::ostream *err_stream, const std::string &file_name)
int stanc_helper(int argc, const char *argv[], std::ostream *out_stream, std::ostream *err_stream)
void print_version(std::ostream *out_stream)
void print_stanc_help(std::ostream *out_stream)
Prints the Stan compiler (stanc) help.

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