34 bool read_until(std::istream &ist,
const char *st) {
35 int i = 0, l = int(strlen(st));
char c;
36 while (!ist.eof() && i < l)
37 { ist.get(c);
if (toupper(c) == toupper(st[i])) i++;
else i = 0; }
38 if (ist.eof())
return false;
else return true;
41 #define get_c__(r, c) { ist.get(c); \ 42 if (ist.eof()) { if (!st.size()) st.push_back('\n'); return r; } \ 43 if (to_up) c = char(toupper(c)); } 45 #define sdouble__(c, e) { st.push_back(c); get_c__(5, d); \ 46 if (d == e) { st.push_back(e); return 6; } \ 47 else { ist.putback(d); return 5; } } \ 50 bool ignore_cr,
bool to_up,
bool read_un_pm,
int *linenb) {
52 char c = char(-1), d, e;
57 if (!ignore_cr && c ==
'\n') {
if (linenb) (*linenb)++;
return 1; }
58 if (isspace(c)) {
while (isspace(c)) get_c__(0, c); }
59 else if (c ==
'%') {
while (c !=
'\n') get_c__(0, c); }
61 if (ist.eof())
break;
else {
63 if (d ==
'.' && !ist.eof()) {
66 while (c !=
'\n') get_c__(0, c);
67 if (linenb) (*linenb)++;
70 else { ist.putback(e); ist.putback(d);
break; }
72 else { ist.putback(d);
break; }
79 if (c ==
'-' || c ==
'+') {
81 if (isdigit(d) || d ==
'.') { st.push_back(c); c = d; }
85 if (isdigit(c) || c ==
'.') {
86 while (isdigit(c) || c ==
'.' || c ==
'e' || c ==
'E') {
88 if (c ==
'e' || c ==
'E') {
90 if (c ==
'+' || c ==
'-') st.push_back(c);
102 if (c ==
'\"' || c ==
'\n')
return 3;
103 if (c ==
'\\') { st.push_back(c); get_c__(3, c); }
113 if (c ==
'\'' || c ==
'\n')
return 3;
114 if (c ==
'\\') { st.push_back(c); get_c__(3, c); }
121 if (isalpha(c) || c ==
'_') {
122 while (isalnum(c) || c ==
'_') {
130 if (c ==
'|') sdouble__(c,
'|');
131 if (c ==
'&') sdouble__(c,
'&');
132 if (c ==
'=') sdouble__(c,
'=');
133 if (c ==
'~') sdouble__(c,
'=');
134 if (c ==
'<') sdouble__(c,
'=');
135 if (c ==
'>') sdouble__(c,
'=');
137 st.push_back(c);
return 5;
140 std::istream& operator>>(std::istream& is,
const skip& t) {
143 while (!is.get(c).eof() && isspace(c)) ;
144 for (i=0; t.s[i]; ++i) {
146 GMM_ASSERT1(toupper(c) == toupper(t.s[i]) && !is.eof(),
147 "expected token '" << t.s <<
"' not found");
152 int casecmp(
const char *a,
const char *b,
unsigned n) {
154 for (i=0; i < n && a[i] && b[i]; ++i) {
155 if (toupper(a[i]) < toupper(b[i]))
return -1;
156 else if (toupper(a[i]) > toupper(b[i]))
return -1;
159 else if (b[i])
return -1;
163 void md_param::parse_error(
const std::string &t) {
164 GMM_ASSERT1(
false,
"Parse error reading " 165 << current_file <<
" line " << current_line <<
" near " << t);
168 void md_param::syntax_error(
const std::string &t) {
169 GMM_ASSERT1(
false,
"Error reading " 170 << current_file <<
" line " << current_line <<
" : " << t);
173 int md_param::get_next_token(std::istream &f) {
174 static int token_type = 0;
176 token_type =
get_token(f, temp_string,
false,
false,
false,
178 token_is_valid =
false;
182 void md_param::valid_token() { token_is_valid =
true; }
184 std::ostream &
operator <<(std::ostream &o,
const md_param::param_value& p) {
185 switch (p.type_of_param()) {
186 case md_param::REAL_VALUE : o << p.real();
break;
187 case md_param::STRING_VALUE : o <<
'\'' << p.string() <<
'\'';
break;
188 case md_param::ARRAY_VALUE :
190 if (p.array().size()) o << p.array()[0];
191 for (
unsigned i = 1; i < p.array().size(); ++i)
192 o <<
", " << p.array()[i];
198 md_param::param_value md_param::read_expression(std::istream &f,
201 int i = get_next_token(f);
203 result = param_value(::strtod(temp_string.c_str(), 0));
206 result = param_value(temp_string);
207 int j = get_next_token(f);
209 result.string() += temp_string;
210 j = get_next_token(f);
215 std::string name(temp_string);
216 if (parameters.find(name) != parameters.end())
217 result = parameters[name];
219 std::stringstream s; s <<
"Parameter " << name <<
" not found";
220 syntax_error(s.str());
224 switch (temp_string[0]) {
227 result = read_expression_list(f, skipped);
228 int j = get_next_token(f);
229 if (j != 5 || temp_string[0] !=
')') parse_error(temp_string);
233 result = read_expression(f, skipped);
234 if (result.type_of_param() != REAL_VALUE)
235 syntax_error(
"Sorry, unary + does not support string " 239 result = read_expression(f, skipped);
240 if (result.type_of_param() != REAL_VALUE)
241 syntax_error(
"Sorry, unary - does not support string " 243 result.real() *= -1.0;
246 result = read_expression(f, skipped);
247 if (result.type_of_param() != REAL_VALUE)
248 syntax_error(
"Sorry, unary ! does not support string " 250 result.real() = !(result.real());
255 result = param_value(ARRAY_VALUE);
257 int j = get_next_token(f);
258 if (j == 5 && temp_string[0] ==
']')
break;
259 if (!first && temp_string[0] !=
',') parse_error(temp_string);
260 if (first) valid_token();
261 result.array().push_back(read_expression_list(f, skipped));
266 default : parse_error(temp_string);
269 else parse_error(temp_string);
274 static void operator_priority_ftool(
int i,
char c,
int &prior,
int &op) {
277 case '*' : prior = 1; op = 1;
return;
278 case '/' : prior = 1; op = 2;
return;
279 case '+' : prior = 2; op = 3;
return;
280 case '-' : prior = 2; op = 4;
return;
281 case '<' : prior = 3; op = 5;
return;
282 case '>' : prior = 3; op = 6;
return;
286 case '<' : prior = 3; op = 7;
return;
287 case '>' : prior = 3; op = 8;
return;
288 case '=' : prior = 3; op = 9;
return;
289 case '~' : prior = 3; op = 10;
return;
290 case '&' : prior = 4; op = 11;
return;
291 case '|' : prior = 4; op = 12;
return;
296 void md_param::do_bin_op(std::vector<md_param::param_value> &value_list,
297 std::vector<int> &op_list,
298 std::vector<int> &prior_list) {
299 param_value &p1(*(value_list.end() - 2));
300 param_value &p2(*(value_list.end() - 1));
301 if (p1.type_of_param() != REAL_VALUE || p2.type_of_param() != REAL_VALUE)
302 syntax_error(
"Sorry, binary operators does not support string " 305 switch (op_list.back()) {
306 case 1 : p1.real() *= p2.real();
break;
307 case 2 : p1.real() /= p2.real();
break;
308 case 3 : p1.real() += p2.real();
break;
309 case 4 : p1.real() -= p2.real();
break;
310 case 5 : p1.real() = (p1.real() < p2.real());
break;
311 case 6 : p1.real() = (p1.real() > p2.real());
break;
312 case 7 : p1.real() = (p1.real() <= p2.real());
break;
313 case 8 : p1.real() = (p1.real() >= p2.real());
break;
314 case 9 : p1.real() = (p1.real() == p2.real());
break;
315 case 10 : p1.real() = (p1.real() != p2.real());
break;
316 case 11 : p1.real() = ((p1.real() != 0.0) && (p2.real() != 0.0));
break;
317 case 12 : p1.real() = ((p1.real() != 0.0) || (p2.real() != 0.0));
break;
319 value_list.pop_back(); op_list.pop_back(); prior_list.pop_back();
323 md_param::param_value md_param::read_expression_list(std::istream &f,
325 std::vector<param_value> value_list;
326 value_list.push_back(read_expression(f, skipped));
327 std::vector<int> op_list, prior_list;
328 int i = get_next_token(f), prior, op;
329 operator_priority_ftool(i, temp_string[0], prior, op);
331 while (!prior_list.empty() && prior_list.back() <= prior)
332 do_bin_op(value_list, op_list, prior_list);
334 value_list.push_back(read_expression(f, skipped));
335 op_list.push_back(op);
336 prior_list.push_back(prior);
338 i = get_next_token(f);
339 operator_priority_ftool(i, temp_string[0], prior, op);
343 while (!prior_list.empty()) do_bin_op(value_list, op_list, prior_list);
345 return value_list[0];
348 int md_param::read_instruction(std::istream &f,
bool skipped) {
350 while (i == 1 || (i == 5 && temp_string[0] ==
';')) i = get_next_token(f);
351 if (i == 0)
return 1;
352 if (i != 4) parse_error(temp_string);
353 if (temp_string ==
"end")
return 1;
354 if (temp_string ==
"else")
return 2;
355 if (temp_string ==
"elseif")
return 3;
356 if (temp_string ==
"if") {
357 param_value p = read_expression_list(f, skipped);
358 if (p.type_of_param() != REAL_VALUE)
359 syntax_error(
"if instruction needs a condition");
360 bool b = (p.real() != 0.0);
361 int j = read_instruction_list(f, !b || skipped);
362 if (j == 0) syntax_error(
"Unterminated if");
364 int k = read_instruction_list(f, b || skipped);
365 if (k != 1) syntax_error(
"Unterminated else");
370 if (b) skipped =
true;
371 p = read_expression_list(f, skipped);
372 if (p.type_of_param() != REAL_VALUE)
373 syntax_error(
"elseif instruction needs a condition");
374 b = (p.real() != 0.0);
375 k = read_instruction_list(f, !b || skipped);
377 k = read_instruction_list(f, b || skipped);
381 if (k != 1) syntax_error(
"Unterminated elseif");
385 if (temp_string ==
"error") {
386 param_value p = read_expression_list(f, skipped);
387 GMM_ASSERT1(skipped,
"Error in parameter file: " << p);
390 std::string name(temp_string);
391 i = get_next_token(f);
392 if (i != 5 || temp_string[0] !=
'=') parse_error(temp_string);
393 param_value result = read_expression_list(f, skipped);
394 i = get_next_token(f);
395 if (i != 0 && i != 1 && (i != 5 || temp_string[0] !=
';'))
396 parse_error(temp_string);
397 if (!skipped) parameters[name]=result;
401 int md_param::read_instruction_list(std::istream &f,
bool skipped) {
402 int i;
while (!(i = read_instruction(f, skipped))) { }
406 void md_param::read_param_file(std::istream &f) {
408 token_is_valid =
false; current_line = 1;
409 if (read_instruction_list(f) > 1)
410 syntax_error(
"Parameter file terminated by an else");
413 void md_param::read_command_line(
int argc,
char *argv[]) {
415 for (
int aa = 1; aa < argc; aa++) {
416 if (argv[aa][0] !=
'-') {
417 current_file = std::string(argv[aa]);
418 std::ifstream f1(current_file.c_str());
419 if (f1) { read_param_file(f1); f1.close(); }
421 std::string r = current_file;
422 current_file +=
".param";
423 std::ifstream f2(current_file.c_str());
424 if (f2) { read_param_file(f2); f2.close(); }
425 else GMM_ASSERT1(
false,
"Parameter file " << r <<
"not found");
428 else if (argv[aa][1] ==
'd') {
429 current_file =
"command line";
430 if (strlen(argv[aa]) == 2)
431 { std::stringstream ss(argv[++aa]); read_param_file(ss); }
433 { std::stringstream ss(&(argv[aa][2])); read_param_file(ss); }
438 double md_param::real_value(
const std::string &name,
const char *comment,
439 double default_val) {
440 if (parameters.find(name) == parameters.end()) {
446 cout <<
"No parameter " << name <<
" found, please enter its value\n";
447 cout << comment <<
" : "; cin >> f;
448 parameters[name] = param_value(f);
451 param_value &p(parameters[name]);
452 GMM_ASSERT1(p.type_of_param() == REAL_VALUE,
453 "Parameter " << name <<
" is not real");
457 long md_param::int_value(
const std::string &name,
const char *comment,
459 if (parameters.find(name) == parameters.end()) {
465 cout <<
"No parameter " << name <<
" found, please enter its value\n";
466 cout << comment <<
" : "; cin >> f;
467 parameters[name] = param_value(
double(f));
470 param_value &p(parameters[name]);
471 GMM_ASSERT1(p.type_of_param() == REAL_VALUE,
472 "Parameter " << name <<
" is not real");
473 return long(p.real());
476 const std::string &md_param::string_value(
const std::string &name,
478 const std::string &default_val) {
479 if (parameters.find(name) == parameters.end()) {
485 cout <<
"No parameter " << name <<
" found, please enter its value\n";
486 cout << comment <<
" : "; cin >> s;
487 parameters[name] = param_value(s);
490 param_value &p(parameters[name]);
491 GMM_ASSERT1(p.type_of_param() == STRING_VALUE,
"Parameter " << name
492 <<
" is not a character string");
496 const std::vector<md_param::param_value> &
497 md_param::array_value(
const std::string &name,
const char *comment) {
499 static std::vector<md_param::param_value> empty_array;
500 if (parameters.find(name) == parameters.end()) {
501 if (comment == 0)
return empty_array;
505 cout <<
"No parameter " << name <<
" found, please enter its value\n";
506 cout << comment <<
" : "; cin >> s;
507 parameters[name] = param_value(s);
510 param_value &p(parameters[name]);
511 GMM_ASSERT1(p.type_of_param() == ARRAY_VALUE,
"Parameter " << name
512 <<
" is not an array");
std::ostream & operator<<(std::ostream &o, const convex_structure &cv)
Print the details of the convex structure cvs to the output stream o.
int get_token(std::istream &ist, std::string &st, bool ignore_cr, bool to_up, bool read_un_pm, int *linenb)
Very simple lexical analysis of general interest for reading small langages with a "MATLAB like" synt...
this is the above solutions for linux, but it still needs to be tested.
defines and typedefs for namespace bgeot