Stan  2.10.0
probability, sampling & optimization
stanc_helper.hpp
Go to the documentation of this file.
1 #ifndef STAN_COMMAND_STANC_HELPER_HPP
2 #define STAN_COMMAND_STANC_HELPER_HPP
3 
4 #include <stan/version.hpp>
5 #include <stan/lang/compiler.hpp>
6 #include <stan/io/cmd_line.hpp>
7 #include <exception>
8 #include <fstream>
9 #include <iostream>
10 #include <stdexcept>
11 #include <string>
12 
13 
14 void print_version(std::ostream* out_stream) {
15  if (!out_stream) return;
16  *out_stream << "stanc version "
18  << "."
20  << "."
22  << std::endl;
23 }
24 
28 void print_stanc_help(std::ostream* out_stream) {
30 
31  if (!out_stream) return;
32 
33  *out_stream << std::endl;
34  print_version(out_stream);
35  *out_stream << std::endl;
36 
37  *out_stream << "USAGE: " << "stanc [options] <model_file>" << std::endl;
38  *out_stream << std::endl;
39 
40  *out_stream << "OPTIONS:" << std::endl;
41  *out_stream << std::endl;
42 
43  print_help_option(out_stream, "help", "", "Display this information");
44 
45  print_help_option(out_stream, "version", "", "Display stanc version number");
46 
47  print_help_option(out_stream, "name", "string",
48  "Model name",
49  "default = \"$model_filename_model\"");
50 
51  print_help_option(out_stream, "o", "file",
52  "Output file for generated C++ code",
53  "default = \"$name.cpp\"");
54 }
55 
56 void delete_file(std::ostream* err_stream,
57  const std::string& file_name) {
58  int deleted = std::remove(file_name.c_str());
59  if (deleted != 0 && file_name.size() > 0)
60  if (err_stream)
61  *err_stream << "Could not remove output file=" << file_name
62  << std::endl;
63 }
64 
65 
66 int stanc_helper(int argc, const char* argv[],
67  std::ostream* out_stream, std::ostream* err_stream) {
68  static const int SUCCESS_RC = 0;
69  static const int EXCEPTION_RC = -1;
70  static const int PARSE_FAIL_RC = -2;
71  static const int INVALID_ARGUMENT_RC = -3;
72 
73  std::string out_file_name; // declare outside of try to delete in catch
74 
75  try {
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 "
130  "number or symbol other than _");
131  throw std::invalid_argument(msg);
132  }
133  for (std::string::iterator strIt = model_name.begin();
134  strIt != model_name.end(); strIt++) {
135  if (!isalnum(*strIt) && *strIt != '_') {
136  std::string msg("model_name must contain only letters, numbers and _");
137  throw std::invalid_argument(msg);
138  }
139  }
140 
141  stan::lang::program prog;
142 
143  std::fstream out(out_file_name.c_str(),
144  std::fstream::out);
145  if (out_stream) {
146  *out_stream << "Model name=" << model_name << std::endl;
147  *out_stream << "Input file=" << in_file_name << std::endl;
148  *out_stream << "Output file=" << out_file_name << std::endl;
149  }
150 
151  bool valid_model
152  = stan::lang::compile(err_stream, in, out, model_name);
153 
154  out.close();
155  if (!valid_model) {
156  if (err_stream)
157  *err_stream << "PARSING FAILED." << std::endl;
158  // FIXME: how to remove triple cut-and-paste?
159  delete_file(out_stream, out_file_name);
160  return PARSE_FAIL_RC;
161  }
162  } catch (const std::invalid_argument& e) {
163  if (err_stream) {
164  *err_stream << std::endl
165  << e.what()
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  << e.what()
174  << std::endl;
175  }
176  delete_file(out_stream, out_file_name);
177  return EXCEPTION_RC;
178  }
179  return SUCCESS_RC;
180 }
181 
182 #endif
bool compile(std::ostream *msgs, std::istream &stan_lang_in, std::ostream &cpp_out, const std::string &model_name)
Read a Stan model specification from the specified input, parse it, and write the C++ code for it to ...
Definition: compiler.hpp:28
bool val(const std::string &key, T &x) const
Returns the value for the key provided.
Definition: cmd_line.hpp:190
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:166
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:204
const std::string MINOR_VERSION
Minor version number for Stan package.
Definition: version.hpp:24
size_t bare_size() const
Return the number of bare arguments.
Definition: cmd_line.hpp:213
const std::string PATCH_VERSION
Patch version for Stan package.
Definition: version.hpp:27
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:231
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:21

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