gambit is hosted by Hepforge, IPPP Durham
GAMBIT  v1.5.0-2191-ga4742ac
a Global And Modular Bsm Inference Tool
screen_print_utils.cpp
Go to the documentation of this file.
1 // GAMBIT: Global and Modular BSM Inference Tool
2 // *********************************************
18 
19 /*
20  * To get the screen, use
21  * int width = get_screen_cols();
22  * This will return -1 if it can't
23  * To print a string through less, do
24  * print_to_screen(string, file_name);
25  * Will print to 'more' if there is no 'less
26  */
27 
28 #include <cstdlib>
29 #include <sstream>
30 #include <fstream>
31 #include <iomanip>
32 #include <utility>
33 
34 #include <iostream>
35 
39 
40 namespace Gambit
41 {
42  /********************************************/
43  /****** adds spaces to fit to screen ********/
44  /********************************************/
45 
46  inline void add_screen_spaces(std::string &str, std::string::size_type size, std::string::size_type indent)
47  {
48  std::stringstream ss(str.substr(indent));
49  std::string word;
50  std::string::size_type words =0;
51 
52  while (ss >> word){words++;}
53  words--;
54  if (words <= 0)
55  return;
56  std::string::size_type to_add = (size - str.length())/(words);
57  std::string::size_type extras = (size - str.length())%(words);
58  std::string::size_type extras_even = words/2;
59  std::string::size_type extras_odd = words - extras_even;
60  if (extras > extras_odd)
61  {
62  extras_even = extras - extras_odd;
63  }
64  else
65  {
66  extras_odd = extras;
67  extras_even = 0;
68  }
69 
70  std::string::size_type pos = str.find_first_not_of(" ", indent);
71  pos = str.find_first_of(" ", pos);
72  int i = 0;
73  while (pos != std::string::npos)
74  {
75  i++;
76  if (i%2 == 0 && extras_even > 0)
77  {
78  str.insert(pos, to_add + 1, ' ');
79  extras_even--;
80  }
81  else if (i%2 == 1 && extras_odd > 0)
82  {
83  str.insert(pos, to_add + 1, ' ');
84  extras_odd--;
85  }
86  else if (to_add > 0)
87  {
88  str.insert(pos, to_add, ' ');
89  }
90 
91  pos = str.find_first_not_of(" ", pos);
92  pos = str.find_first_of(" ", pos);
93  }
94  }
95 
96  /*********************************************/
97  /****** formats output for the screen ********/
98  /*********************************************/
99 
100  std::string format_for_screen(const std::string &input_string)
101  {
102  int cols = get_screen_cols();
103  std::string output_string, str;
104  std::stringstream ss(input_string);
105 
106  if (cols > 0)
107  {
108  std::string::size_type cols_pos = cols;
109  while (std::getline(ss, str))
110  {
111  bool add_n = false;
112  std::string line = str;
113 
114  if (str.length() >= 16 && str.substr(0, 16) == "#remove_newlines")
115  {
116  bool ck_space = false;
117  line = "";
118 
119  while(std::getline(ss, str))
120  {
121  if (str.length() >= 21 && str.substr(0, 21) == "#dont_remove_newlines")
122  {
123  break;
124  }
125  else if (str.find_first_not_of(" ") == std::string::npos)
126  {
127  add_n = true;
128  break;
129  }
130  else if (!(str.length() > 0 && str[0] == '#'))
131  {
132  if (ck_space)
133  {
134  if (str[0] != ' ')
135  line += " ";
136 
137  ck_space = false;
138  }
139 
140  if (str[str.length()-1] != ' ')
141  ck_space = true;
142 
143  line += str;
144  }
145  }
146  }
147 
148  std::string::size_type len = line.find_last_not_of(" ");
149  if (len == std::string::npos || line.length() == 0)
150  {
151  output_string += "\n";
152  }
153  else if (!(line.length() > 0 && line[0] == '#'))
154  {
155  line = line.substr(0, len+1);
156 
157  std::string::size_type cols_corr = line.find_first_of("\x1b");
158  std::string::size_type indent = line.find_first_not_of(" ");
159  std::string::size_type colon_indent = line.find_first_of(":");
160 
161  if (colon_indent != std::string::npos && 2*colon_indent < cols_pos)
162  {
163  indent = line.find_first_not_of(" ", colon_indent +1);
164  }
165 
166  for (;;)
167  {
168  if ((cols_corr == std::string::npos) && (line.length() > cols_pos))
169  {
170  std::string temp = separate_line(line, indent, cols_pos);
171  add_screen_spaces(temp, cols_pos, indent);
172  output_string += temp + "\n";
173  }
174  else
175  {
176  output_string += line + "\n";
177  break;
178  }
179  }
180 
181  if (add_n)
182  output_string += "\n";
183  }
184  }
185  }
186  else
187  {
188  while(std::getline(ss, str))
189  {
190  if (!(str.length() > 0 && str[0] == '#'))
191  {
192  str = str.substr(0, str.find_last_not_of(" ")+1);
193  output_string += str + "\n";
194  }
195  }
196  }
197 
198  return output_string;
199  }
200 
201  /*************************************************/
202  /****** pipes output through less or more ********/
203  /*************************************************/
204 
205  void print_to_screen(const std::string &file_in, const std::string &name)
206  {
207  if (file_in.empty()) return;
208 
209  std::string file = format_for_screen(file_in);
210  char temp_file[20] = "_gambit_temp_XXXXXX";
211  int err = mkstemp(temp_file);
212  if (err == -1) utils_error().raise(LOCAL_INFO, "Error returned from mkstemp.");
213  std::ofstream out(temp_file);
214  out << file << std::flush;
215  if (std::system("command -v less >/dev/null"))
216  {
217  err = std::system((std::string("more -d ") + std::string(temp_file)).c_str());
218  if (err) utils_error().raise(LOCAL_INFO, "Error returned from call to more.");
219  }
220  else
221  {
222  err = std::system((std::string("less -S -R -P\"Gambit diagnostic ") + name + std::string(" line %l (press h for help or q to quit)\" ") + std::string(temp_file)).c_str());
223  if (err) utils_error().raise(LOCAL_INFO, "Error returned from call to less.");
224  }
225  err = std::system(("rm -f " + std::string(temp_file) + " >/dev/null").c_str());
226  if (err) utils_error().raise(LOCAL_INFO, "Error returned from attempt to remove temp file.");
227  }
228 
229 }
General small utility macros.
EXPORT_SYMBOLS error & utils_error()
Utility errors.
#define LOCAL_INFO
Definition: local_info.hpp:34
void add_screen_spaces(std::string &str, std::string::size_type size, std::string::size_type indent)
int get_screen_cols()
Utility Functions for the Gambit Scanner.
std::string separate_line(std::string &line, std::string::size_type indent, std::string::size_type cols_pos)
std::string str
Shorthand for a standard string.
Definition: Analysis.hpp:35
Exception objects required for standalone compilation.
TODO: see if we can use this one:
Definition: Analysis.hpp:33
std::string format_for_screen(const std::string &input_string)
void print_to_screen(const std::string &file_in, const std::string &name)